package scope

import "testing"

func TestCanView(t *testing.T) {
	tests := []struct {
		name     string
		role     Role
		scope    Scope
		target   Scope
		expected bool
	}{
		{"kpm sees anything", RoleKPM, Scope{}, Scope{State: "Selangor", PPD: "PPD A", School: "S1"}, true},
		{"jpn same state", RoleJPN, Scope{State: "Johor"}, Scope{State: "Johor", School: "S9"}, true},
		{"jpn other state", RoleJPN, Scope{State: "Johor"}, Scope{State: "Kedah"}, false},
		{"ppd same district", RolePPD, Scope{State: "Johor", PPD: "PPD JB"}, Scope{State: "Johor", PPD: "PPD JB"}, true},
		{"ppd other district", RolePPD, Scope{State: "Johor", PPD: "PPD JB"}, Scope{State: "Johor", PPD: "PPD Muar"}, false},
		{"teacher same school", RoleTeacher, Scope{School: "S1"}, Scope{School: "S1"}, true},
		{"teacher other school", RoleTeacher, Scope{School: "S1"}, Scope{School: "S2"}, false},
		{"murid same school", RoleMurid, Scope{School: "S1"}, Scope{School: "S1"}, true},
		{"empty scope denied", RoleJPN, Scope{}, Scope{State: "Johor"}, false},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			p := Principal{Role: tc.role, Scope: tc.scope}
			if got := p.CanView(tc.target); got != tc.expected {
				t.Fatalf("CanView() = %v, want %v", got, tc.expected)
			}
		})
	}
}

func TestAtLeast(t *testing.T) {
	if !(Principal{Role: RoleKPM}).AtLeast(RoleTeacher) {
		t.Fatal("kpm should be at least teacher")
	}
	if (Principal{Role: RoleMurid}).AtLeast(RolePPD) {
		t.Fatal("murid should not be at least ppd")
	}
}

func TestParseRole(t *testing.T) {
	if ParseRole("jpn") != RoleJPN {
		t.Fatal("expected jpn")
	}
	if ParseRole("bogus") != RoleMurid {
		t.Fatal("unknown role should default to murid")
	}
}
