package allowlist

import (
	"slices"
	"sync"
)

type LockList struct {
	OrgIds         []uint64 `yaml:"orgIds"`
	SuperUsers     []string `yaml:"superUsers"`
	LockAll        bool     `yaml:"lockAll"`
	lockCache      map[uint64]bool
	superUserCache map[string]bool
	lock           *sync.Mutex
}

// For test only
func (l *LockList) AddLockOrgId(orgId uint64) {
	l.lock.Lock()
	defer l.lock.Unlock()

	l.OrgIds = append(l.OrgIds, orgId)
	l.lockCache[orgId] = true
}

// For test only
func (l *LockList) Reset() {
	l.lock.Lock()
	defer l.lock.Unlock()

	l.OrgIds = []uint64{}
	l.lockCache = map[uint64]bool{}
}

func (l *LockList) IsLockOrgId(orgId uint64) bool {
	l.lock.Lock()
	defer l.lock.Unlock()

	if l.LockAll {
		return true
	}

	if exist, lock := l.lockCache[orgId]; exist {
		return lock
	}

	if slices.Contains(l.OrgIds, orgId) {
		l.lockCache[orgId] = true
		return true
	}

	l.lockCache[orgId] = false
	return false
}

func (l *LockList) IsSuperUser(user string) bool {
	l.lock.Lock()
	defer l.lock.Unlock()

	if exist, super := l.superUserCache[user]; exist {
		return super
	}

	if slices.Contains(l.SuperUsers, user) {
		l.superUserCache[user] = true
		return true
	}

	l.superUserCache[user] = false
	return false
}

func (l *LockList) sort() {
	l.lock.Lock()
	defer l.lock.Unlock()

	slices.Sort(l.OrgIds)
}
