package scope

type Role string

const (
	RoleMurid   Role = "murid"
	RoleTeacher Role = "teacher"
	RolePPD     Role = "ppd"
	RoleJPN     Role = "jpn"
	RoleKPM     Role = "kpm"
)

func ParseRole(value string) Role {
	switch Role(value) {
	case RoleMurid, RoleTeacher, RolePPD, RoleJPN, RoleKPM:
		return Role(value)
	default:
		return RoleMurid
	}
}

type Scope struct {
	State  string
	PPD    string
	School string
}

type Principal struct {
	UserID int64
	Role   Role
	Scope  Scope
}

func (p Principal) IsNational() bool {
	return p.Role == RoleKPM
}

func (p Principal) CanView(target Scope) bool {
	switch p.Role {
	case RoleKPM:
		return true
	case RoleJPN:
		return p.Scope.State != "" && p.Scope.State == target.State
	case RolePPD:
		return p.Scope.State != "" && p.Scope.State == target.State &&
			p.Scope.PPD != "" && p.Scope.PPD == target.PPD
	case RoleTeacher, RoleMurid:
		return p.Scope.School != "" && p.Scope.School == target.School
	default:
		return false
	}
}

func (p Principal) AtLeast(role Role) bool {
	return rank(p.Role) >= rank(role)
}

func rank(role Role) int {
	switch role {
	case RoleKPM:
		return 5
	case RoleJPN:
		return 4
	case RolePPD:
		return 3
	case RoleTeacher:
		return 2
	case RoleMurid:
		return 1
	default:
		return 0
	}
}
