package auth

import (
	"os"
	"strings"
	"testing"
)

// Buyers start at Bronze — never Silver or above.
//
// The tier catalogue has a 'silver' row (migration 000077) and the checkout
// pricing engine reads membership_tiers directly, so an accidental
// 'silver' (or higher) on registration would immediately grant a bigger
// discount than the business intends. These assertions pin the starting
// tier at the SQL that writes it, so a future copy/paste cannot raise it.
func TestRegistrationStartsAtBronze(t *testing.T) {
	src, err := readSource("repository.go")
	if err != nil {
		t.Skipf("source not readable in this build: %v", err)
	}

	// The INSERT that enrols a new buyer must name 'bronze' explicitly and
	// must not name any other tier.
	insert := between(src, "INSERT INTO memberships (member_number, customer_id, tier", "ON CONFLICT (customer_id) DO NOTHING")
	if insert == "" {
		t.Fatal("registration membership INSERT not found — did the enrolment move?")
	}
	if !strings.Contains(insert, "'bronze'") {
		t.Error("registration does not write 'bronze' as the starting tier")
	}
	for _, higher := range []string{"'silver'", "'gold'", "'platinum'", "'tier_"} {
		if strings.Contains(insert, higher) {
			t.Errorf("registration writes %s — buyers must start at bronze", higher)
		}
	}
}

// The history row must agree with the membership row: a bronze membership with
// a "silver" history entry would make the audit trail lie about the starting
// level.
func TestRegistrationHistoryMatchesBronze(t *testing.T) {
	src, err := readSource("repository.go")
	if err != nil {
		t.Skipf("source not readable in this build: %v", err)
	}
	hist := between(src, "INSERT INTO membership_tier_history (membership_id, to_tier, reason", "membership created")
	if hist == "" {
		t.Fatal("tier history INSERT not found")
	}
	if !strings.Contains(hist, "'bronze'") {
		t.Error("tier history does not record 'bronze' for the starting membership")
	}
}

// readSource loads a file from this package directory without importing os in
// every caller (kept tiny on purpose: one helper, two tests).
func readSource(name string) (string, error) {
	b, err := os.ReadFile(name)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

// between returns the slice of src from the first occurrence of start to the
// first occurrence of end after it, or "" when either marker is missing.
func between(src, start, end string) string {
	i := strings.Index(src, start)
	if i < 0 {
		return ""
	}
	j := strings.Index(src[i:], end)
	if j < 0 {
		return src[i:]
	}
	return src[i : i+j]
}
