package permissions

// PlatformIdentity maps a platform user to a Cyrene user.
type PlatformIdentity struct {
	Platform    string `yaml:"platform" json:"platform"`
	PlatformUID string `yaml:"platform_uid" json:"platform_uid"`
	CyreneUser  string `yaml:"cyrene_user_id" json:"cyrene_user_id"`
	Nickname    string `yaml:"nickname" json:"nickname"`

	PermissionLevel string   `yaml:"permission_level" json:"permission_level"`
	AllowedTools    []string `yaml:"allowed_tools,omitempty" json:"allowed_tools,omitempty"`
	IoTDevices      []string `yaml:"iot_devices,omitempty" json:"iot_devices,omitempty"`
}

// Level represents a permission level.
type Level string

const (
	LevelAdmin      Level = "admin"
	LevelFull       Level = "full"
	LevelBasic      Level = "basic"
	LevelRestricted Level = "restricted"
)

// Checker validates whether an operation is allowed for a given identity.
type Checker struct{}

func NewChecker() *Checker { return &Checker{} }

// CanChat checks if the identity can send chat messages.
func (c *Checker) CanChat(id *PlatformIdentity) bool {
	return id != nil
}

// CanControlIoT checks if the identity can control IoT devices.
func (c *Checker) CanControlIoT(id *PlatformIdentity) bool {
	if id == nil {
		return false
	}
	switch Level(id.PermissionLevel) {
	case LevelAdmin, LevelFull:
		return true
	default:
		return false
	}
}

// CanQueryIoT checks if the identity can query IoT device state.
func (c *Checker) CanQueryIoT(id *PlatformIdentity) bool {
	if id == nil {
		return false
	}
	switch Level(id.PermissionLevel) {
	case LevelAdmin, LevelFull, LevelBasic:
		return true
	default:
		return false
	}
}

// CanAccessMemory checks if the identity can view memories.
func (c *Checker) CanAccessMemory(id *PlatformIdentity) bool {
	if id == nil {
		return false
	}
	return Level(id.PermissionLevel) != LevelRestricted
}

// CanManageSystem checks if the identity can modify system config.
func (c *Checker) CanManageSystem(id *PlatformIdentity) bool {
	if id == nil {
		return false
	}
	return Level(id.PermissionLevel) == LevelAdmin
}

// IsAdmin checks if the identity has admin privileges.
func (c *Checker) IsAdmin(id *PlatformIdentity) bool {
	if id == nil {
		return false
	}
	return Level(id.PermissionLevel) == LevelAdmin
}

// AllowedTool checks if a specific tool is allowed for this identity.
func (c *Checker) AllowedTool(id *PlatformIdentity, toolName string) bool {
	if id == nil {
		return false
	}
	if Level(id.PermissionLevel) == LevelAdmin {
		return true
	}
	for _, t := range id.AllowedTools {
		if t == toolName {
			return true
		}
	}
	return false
}

// AllowedIoTDevice checks if a specific device can be controlled by this identity.
func (c *Checker) AllowedIoTDevice(id *PlatformIdentity, deviceID string) bool {
	if id == nil {
		return false
	}
	if Level(id.PermissionLevel) == LevelAdmin {
		return true
	}
	for _, d := range id.IoTDevices {
		if d == deviceID {
			return true
		}
	}
	return false
}
