package airrescuechecklist

import "testing"

func TestAirRescuerChecklistScopeHelpers(t *testing.T) {
	persistedScopes := []string{
		AirRescuerChecklistScopeTA,
		AirRescuerChecklistScopeMO,
		AirRescuerChecklistScopeDI,
		AirRescuerChecklistScopeMI,
		AirRescuerChecklistScopeDO,
		AirRescuerChecklistScopeFR,
		AirRescuerChecklistScopeSA,
		AirRescuerChecklistScopeSO,
		AirRescuerChecklistScopeM10,
		AirRescuerChecklistScopeM15,
		AirRescuerChecklistScopeM20,
		AirRescuerChecklistScopeM25,
		AirRescuerChecklistScopeDS,
	}

	for _, scope := range persistedScopes {
		if !IsAirRescuerChecklistPersistedScope(scope) {
			t.Fatalf("expected persisted scope valid: %s", scope)
		}
		if !IsAirRescuerChecklistPersistedScope(" " + scope + " ") {
			t.Fatalf("expected persisted scope valid with trim: %s", scope)
		}
		if !IsAirRescuerChecklistPersistedScope(lower(scope)) {
			t.Fatalf("expected persisted scope valid with lowercase: %s", scope)
		}
		if !IsAirRescuerChecklistQueryScope(scope) {
			t.Fatalf("expected query scope valid: %s", scope)
		}
		if !IsAirRescuerChecklistScope(scope) {
			t.Fatalf("expected compatibility scope valid: %s", scope)
		}
	}

	if IsAirRescuerChecklistPersistedScope(AirRescuerChecklistScopeCAT) {
		t.Fatalf("expected CAT not persisted")
	}
	if !IsAirRescuerChecklistQueryScope(AirRescuerChecklistScopeCAT) {
		t.Fatalf("expected CAT valid for query")
	}
	if IsAirRescuerChecklistQueryScope("UNKNOWN") {
		t.Fatalf("expected unknown query scope invalid")
	}
	if IsAirRescuerChecklistScope("UNKNOWN") {
		t.Fatalf("expected unknown compatibility scope invalid")
	}

	englishAliases := map[string]string{
		"daily":     AirRescuerChecklistScopeTA,
		"tuesday":   AirRescuerChecklistScopeDI,
		"wednesday": AirRescuerChecklistScopeMI,
		"thursday":  AirRescuerChecklistScopeDO,
		"sunday":    AirRescuerChecklistScopeSO,
		"deadline":  AirRescuerChecklistScopeDS,
		"overview":  AirRescuerChecklistScopeCAT,
		"tu":        AirRescuerChecklistScopeDI,
		"we":        AirRescuerChecklistScopeMI,
		"th":        AirRescuerChecklistScopeDO,
		"su":        AirRescuerChecklistScopeSO,
	}

	for alias, expected := range englishAliases {
		if got := CanonicalizeAirRescuerChecklistScope(alias); got != expected {
			t.Fatalf("expected alias %s canonicalized to %s, got %s", alias, expected, got)
		}
	}

	if !IsAirRescuerChecklistPersistedScope("tu") {
		t.Fatalf("expected TU alias valid as persisted scope")
	}
	if !IsAirRescuerChecklistQueryScope("overview") {
		t.Fatalf("expected OVERVIEW alias valid as query scope")
	}
}

func TestAirRescuerChecklistScopeDisplayName(t *testing.T) {
	if got := AirRescuerChecklistScopeDisplayName(AirRescuerChecklistScopeCAT); got != "Category" {
		t.Fatalf("unexpected CAT display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayName(" mo "); got != "Monday" {
		t.Fatalf("unexpected MO display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayName("x"); got != "X" {
		t.Fatalf("unexpected fallback display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayName("tu"); got != "Tuesday" {
		t.Fatalf("unexpected TU display name: %s", got)
	}
}

func TestAirRescuerChecklistScopeDisplayNameDE(t *testing.T) {
	if got := AirRescuerChecklistScopeDisplayNameDE(AirRescuerChecklistScopeCAT); got != "Category" {
		t.Fatalf("unexpected CAT DE display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayNameDE(" mo "); got != "Montag" {
		t.Fatalf("unexpected MO DE display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayNameDE("x"); got != "X" {
		t.Fatalf("unexpected DE fallback display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayNameDE("thursday"); got != "Donnerstag" {
		t.Fatalf("unexpected THURSDAY DE display name: %s", got)
	}
	if got := AirRescuerChecklistScopeDisplayNameDE(AirRescuerChecklistScopeDS); got != "Deadline" {
		t.Fatalf("unexpected DS DE display name: %s", got)
	}
}

func TestAirRescuerChecklistScopeCodes(t *testing.T) {
	if got := AirRescuerChecklistScopeCodeEN(AirRescuerChecklistScopeTA); got != "DA" {
		t.Fatalf("unexpected TA EN code: %s", got)
	}
	if got := AirRescuerChecklistScopeCodeEN("thursday"); got != "TH" {
		t.Fatalf("unexpected THURSDAY EN code: %s", got)
	}
	if got := AirRescuerChecklistScopeCodeEN("x"); got != "X" {
		t.Fatalf("unexpected EN fallback code: %s", got)
	}

	if got := AirRescuerChecklistScopeCodeDE(AirRescuerChecklistScopeDI); got != AirRescuerChecklistScopeDI {
		t.Fatalf("unexpected DI DE code: %s", got)
	}
	if got := AirRescuerChecklistScopeCodeDE("tu"); got != AirRescuerChecklistScopeDI {
		t.Fatalf("unexpected TU DE code: %s", got)
	}
}

func TestAirRescuerChecklistPersistedScopeOrderReturnsCopy(t *testing.T) {
	first := AirRescuerChecklistPersistedScopeOrder()
	if len(first) != 13 {
		t.Fatalf("unexpected persisted scope order size: %d", len(first))
	}
	if first[0] != AirRescuerChecklistScopeTA || first[len(first)-1] != AirRescuerChecklistScopeDS {
		t.Fatalf("unexpected persisted scope order: %+v", first)
	}

	first[0] = "BROKEN"
	second := AirRescuerChecklistPersistedScopeOrder()
	if second[0] != AirRescuerChecklistScopeTA {
		t.Fatalf("expected second call to return independent copy, got: %s", second[0])
	}
}

func lower(s string) string {
	out := make([]byte, 0, len(s))
	for i := 0; i < len(s); i++ {
		ch := s[i]
		if ch >= 'A' && ch <= 'Z' {
			ch = ch + ('a' - 'A')
		}
		out = append(out, ch)
	}
	return string(out)
}
