package privilege

import "slices"

type (
	PrivilegeType          string
	PrivilegePhase         string
	ApprovalPrivilegeScope string
)

const (
	PrivilegeTypeApproval PrivilegeType = "approval"

	PrivilegePhaseCreated    PrivilegePhase = "created"
	PrivilegePhaseApproving  PrivilegePhase = "approving"
	PrivilegePhaseActive     PrivilegePhase = "active"
	PrivilegePhaseRevoked    PrivilegePhase = "revoked"
	PrivilegePhaseUnapproved PrivilegePhase = "unapproved"

	PrivilegeSourceOpsPortal    string = "ops-portal"
	PrivilegeSourceOncallerAuto string = "oncaller-auto"
	PrivilegeSourceSEEAuto      string = "see-auto"

	PrivilegeApprovalScopeJumpService ApprovalPrivilegeScope = "jump-service"
)

var (
	PrivilegeTypeValues []PrivilegeType = []PrivilegeType{
		PrivilegeTypeApproval,
	}

	PrivilegePhaseValues []PrivilegePhase = []PrivilegePhase{
		PrivilegePhaseCreated, PrivilegePhaseApproving, PrivilegePhaseActive,
		PrivilegePhaseRevoked, PrivilegePhaseUnapproved,
	}
	PrivilegePhaseFinishedValues []PrivilegePhase = []PrivilegePhase{
		PrivilegePhaseRevoked, PrivilegePhaseUnapproved,
	}

	ApprovalPrivilegeScopeValues []ApprovalPrivilegeScope = []ApprovalPrivilegeScope{
		PrivilegeApprovalScopeJumpService,
	}
)

type ApprovalPrivilegeContent struct {
	Scopes []ApprovalPrivilegeScope `json:"scopes"`
}

type PrivilegeContent struct {
	Approval *ApprovalPrivilegeContent `json:"approval_scope,omitempty"`
}

type PrivilegeBinding struct {
	ID   uint64 `json:"id"`
	User string `json:"user"` // email
} // @name privilege.PrivilegeBinding

type Privilege struct {
	ID         uint64              `json:"id"`
	CreatedAt  int64               `json:"created_at"`
	Type       PrivilegeType       `json:"type"`
	Source     string              `json:"source"`
	Content    PrivilegeContent    `json:"content"`
	Reason     string              `json:"reason"`
	ExpiredAt  int64               `json:"expired_at"`
	ClosedAt   *int64              `json:"closed_at"`
	Applicant  string              `json:"applicant"`
	Phase      PrivilegePhase      `json:"phase"`
	ApprovalID uint64              `json:"approval_id"`
	Bindings   []*PrivilegeBinding `json:"bindings"`
} // @name privilege.Privilege

func (p *Privilege) HasApprovalPrivilegeForUser(user string, scope ApprovalPrivilegeScope) bool {
	if p.Type != PrivilegeTypeApproval {
		return false
	}
	if !slices.ContainsFunc(p.Bindings, func(binding *PrivilegeBinding) bool { return binding.User == user }) {
		return false
	}

	return slices.Contains(p.Content.Approval.Scopes, scope)
}
