package roles

import (
	"context"
	"time"

	"chorus.services/bzzz/pkg/security"
	"chorus.services/bzzz/pkg/ucxl"
	slurpContext "chorus.services/bzzz/pkg/slurp/context"
)

// RoleManager handles definition and management of roles and permissions
//
// This is the primary interface for creating, updating, and managing roles
// and their associated permissions within the SLURP system.
type RoleManager interface {
	// CreateRole creates a new role with specified permissions
	CreateRole(ctx context.Context, role *Role) error
	
	// UpdateRole updates an existing role
	UpdateRole(ctx context.Context, role *Role) error
	
	// DeleteRole removes a role from the system
	DeleteRole(ctx context.Context, roleID string) error
	
	// GetRole retrieves a specific role
	GetRole(ctx context.Context, roleID string) (*Role, error)
	
	// ListRoles lists all roles with optional filtering
	ListRoles(ctx context.Context, filter *RoleFilter) ([]*Role, error)
	
	// AssignRole assigns a role to a user or entity
	AssignRole(ctx context.Context, userID, roleID string) error
	
	// RevokeRole revokes a role from a user or entity
	RevokeRole(ctx context.Context, userID, roleID string) error
	
	// GetUserRoles gets all roles assigned to a user
	GetUserRoles(ctx context.Context, userID string) ([]*Role, error)
	
	// CreateRoleHierarchy establishes parent-child relationships between roles
	CreateRoleHierarchy(ctx context.Context, parentRoleID, childRoleID string) error
	
	// GetRoleHierarchy gets the complete role hierarchy
	GetRoleHierarchy(ctx context.Context) (*RoleHierarchy, error)
	
	// ValidateRole validates role definition and permissions
	ValidateRole(ctx context.Context, role *Role) (*RoleValidation, error)
	
	// GetRoleStats returns role management statistics
	GetRoleStats(ctx context.Context) (*RoleStatistics, error)
}

// AccessController handles access control decision making and enforcement
//
// Provides centralized access control decisions based on roles, permissions,
// and context requirements with support for dynamic evaluation and caching.
type AccessController interface {
	// CheckPermission checks if a user has a specific permission
	CheckPermission(ctx context.Context, userID string, permission Permission) (bool, error)
	
	// CheckContextAccess checks if a user can access specific context
	CheckContextAccess(ctx context.Context, userID string, address ucxl.Address, accessType AccessType) (bool, error)
	
	// CheckAccessLevel checks if a user meets the required access level
	CheckAccessLevel(ctx context.Context, userID string, requiredLevel security.AccessLevel) (bool, error)
	
	// BatchCheckPermissions checks multiple permissions efficiently
	BatchCheckPermissions(ctx context.Context, userID string, permissions []Permission) (map[Permission]bool, error)
	
	// EvaluateContextPermissions evaluates all relevant permissions for context
	EvaluateContextPermissions(ctx context.Context, userID string, node *slurpContext.ContextNode) (*ContextPermissions, error)
	
	// GetUserAccessLevel gets the maximum access level for a user
	GetUserAccessLevel(ctx context.Context, userID string) (security.AccessLevel, error)
	
	// CreateAccessToken creates a time-limited access token
	CreateAccessToken(ctx context.Context, userID string, permissions []Permission, ttl time.Duration) (*AccessToken, error)
	
	// ValidateAccessToken validates and extracts permissions from access token
	ValidateAccessToken(ctx context.Context, token string) (*TokenValidation, error)
	
	// GetAccessDecisionHistory gets history of access decisions for audit
	GetAccessDecisionHistory(ctx context.Context, userID string, timeRange time.Duration) ([]*AccessDecision, error)
	
	// GetAccessStats returns access control statistics
	GetAccessStats() (*AccessStatistics, error)
}

// ContextFilter handles role-based filtering of context information
//
// Filters context data based on user roles and permissions to ensure
// appropriate information visibility and data protection.
type ContextFilter interface {
	// FilterContext filters context based on user role and permissions
	FilterContext(ctx context.Context, node *slurpContext.ContextNode, userID string) (*slurpContext.ContextNode, error)
	
	// FilterResolvedContext filters resolved context for role-based access
	FilterResolvedContext(ctx context.Context, resolved *slurpContext.ResolvedContext, userID string) (*slurpContext.ResolvedContext, error)
	
	// BatchFilterContexts filters multiple contexts efficiently
	BatchFilterContexts(ctx context.Context, nodes []*slurpContext.ContextNode, userID string) ([]*slurpContext.ContextNode, error)
	
	// GetFilteredFields gets list of fields that would be filtered for user
	GetFilteredFields(ctx context.Context, node *slurpContext.ContextNode, userID string) ([]string, error)
	
	// ApplySecurityLabels applies security labels to context based on content
	ApplySecurityLabels(ctx context.Context, node *slurpContext.ContextNode) (*LabeledContext, error)
	
	// GetRoleSpecificView gets context optimized for specific role perspective
	GetRoleSpecificView(ctx context.Context, node *slurpContext.ContextNode, roleID string) (*RoleContextView, error)
	
	// SetFilteringPolicy configures filtering policy and rules
	SetFilteringPolicy(policy *FilteringPolicy) error
	
	// GetFilteringStats returns context filtering statistics
	GetFilteringStats() (*FilteringStatistics, error)
}

// PermissionEvaluator handles dynamic evaluation of permissions
//
// Provides sophisticated permission evaluation including conditional
// permissions, time-based access, and context-dependent authorization.
type PermissionEvaluator interface {
	// EvaluatePermission evaluates a permission with context and conditions
	EvaluatePermission(ctx context.Context, userID string, permission Permission, evalContext *EvaluationContext) (*PermissionEvaluation, error)
	
	// EvaluateConditionalPermission evaluates permission with conditions
	EvaluateConditionalPermission(ctx context.Context, userID string, permission *ConditionalPermission) (bool, error)
	
	// EvaluateTimeBasedPermission evaluates time-restricted permission
	EvaluateTimeBasedPermission(ctx context.Context, userID string, permission Permission, timeWindow *TimeWindow) (bool, error)
	
	// GetEffectivePermissions gets all effective permissions for user in context
	GetEffectivePermissions(ctx context.Context, userID string, evalContext *EvaluationContext) ([]Permission, error)
	
	// CreatePermissionRule creates custom permission evaluation rule
	CreatePermissionRule(ctx context.Context, rule *PermissionRule) error
	
	// UpdatePermissionRule updates existing permission rule
	UpdatePermissionRule(ctx context.Context, rule *PermissionRule) error
	
	// DeletePermissionRule removes permission rule
	DeletePermissionRule(ctx context.Context, ruleID string) error
	
	// ListPermissionRules lists all permission rules
	ListPermissionRules(ctx context.Context) ([]*PermissionRule, error)
	
	// GetEvaluationStats returns permission evaluation statistics
	GetEvaluationStats() (*EvaluationStatistics, error)
}

// AuditLogger handles logging of access control events
//
// Provides comprehensive audit logging for access control decisions,
// permission changes, and security-relevant events for compliance
// and security analysis.
type AuditLogger interface {
	// LogAccessDecision logs an access control decision
	LogAccessDecision(ctx context.Context, decision *AccessDecision) error
	
	// LogPermissionChange logs changes to permissions or roles
	LogPermissionChange(ctx context.Context, change *PermissionChange) error
	
	// LogSecurityEvent logs security-relevant events
	LogSecurityEvent(ctx context.Context, event *SecurityEvent) error
	
	// GetAuditLog retrieves audit log entries with filtering
	GetAuditLog(ctx context.Context, filter *AuditFilter) ([]*AuditEntry, error)
	
	// ExportAuditLog exports audit log in specified format
	ExportAuditLog(ctx context.Context, format string, filter *AuditFilter) ([]byte, error)
	
	// GetAuditStats returns audit logging statistics
	GetAuditStats(ctx context.Context) (*AuditStatistics, error)
	
	// SetRetentionPolicy sets audit log retention policy
	SetRetentionPolicy(policy *RetentionPolicy) error
	
	// ArchiveOldLogs archives old audit logs
	ArchiveOldLogs(ctx context.Context, olderThan time.Time) (*ArchiveResult, error)
}

// EncryptionManager handles role-based encryption and key management
//
// Manages encryption keys and operations for role-based access control,
// integrating with the BZZZ crypto system for secure context storage
// and distribution.
type EncryptionManager interface {
	// EncryptForRoles encrypts context data for specific roles
	EncryptForRoles(ctx context.Context, data []byte, roles []string) (*EncryptedData, error)
	
	// DecryptForUser decrypts data based on user's roles and permissions
	DecryptForUser(ctx context.Context, encryptedData *EncryptedData, userID string) ([]byte, error)
	
	// GenerateRoleKey generates encryption key for a role
	GenerateRoleKey(ctx context.Context, roleID string) (*RoleKey, error)
	
	// RotateRoleKeys rotates encryption keys for roles
	RotateRoleKeys(ctx context.Context, roles []string) (*KeyRotationResult, error)
	
	// GetRoleKey retrieves encryption key for a role
	GetRoleKey(ctx context.Context, roleID string) (*RoleKey, error)
	
	// RevokeRoleKey revokes encryption key for a role
	RevokeRoleKey(ctx context.Context, roleID string) error
	
	// ValidateEncryptedData validates integrity of encrypted data
	ValidateEncryptedData(ctx context.Context, encryptedData *EncryptedData) (bool, error)
	
	// GetEncryptionStats returns encryption operation statistics
	GetEncryptionStats() (*EncryptionStatistics, error)
}

// PolicyManager handles role-based policy definition and enforcement
type PolicyManager interface {
	// CreatePolicy creates a new access control policy
	CreatePolicy(ctx context.Context, policy *AccessPolicy) error
	
	// UpdatePolicy updates existing access control policy
	UpdatePolicy(ctx context.Context, policy *AccessPolicy) error
	
	// DeletePolicy removes an access control policy
	DeletePolicy(ctx context.Context, policyID string) error
	
	// GetPolicy retrieves a specific policy
	GetPolicy(ctx context.Context, policyID string) (*AccessPolicy, error)
	
	// ListPolicies lists all policies with optional filtering
	ListPolicies(ctx context.Context, filter *PolicyFilter) ([]*AccessPolicy, error)
	
	// EvaluatePolicy evaluates policy against access request
	EvaluatePolicy(ctx context.Context, policyID string, request *AccessRequest) (*PolicyEvaluation, error)
	
	// GetApplicablePolicies gets policies applicable to user and resource
	GetApplicablePolicies(ctx context.Context, userID string, resource string) ([]*AccessPolicy, error)
	
	// ValidatePolicy validates policy definition and rules
	ValidatePolicy(ctx context.Context, policy *AccessPolicy) (*PolicyValidation, error)
}

// SessionManager handles user session management and context
type SessionManager interface {
	// CreateSession creates new user session with role context
	CreateSession(ctx context.Context, userID string, roles []string) (*UserSession, error)
	
	// GetSession retrieves existing user session
	GetSession(ctx context.Context, sessionID string) (*UserSession, error)
	
	// UpdateSession updates session with new permissions or context
	UpdateSession(ctx context.Context, sessionID string, updates *SessionUpdate) error
	
	// RevokeSession revokes user session
	RevokeSession(ctx context.Context, sessionID string) error
	
	// ListActiveSessions lists all active sessions
	ListActiveSessions(ctx context.Context) ([]*UserSession, error)
	
	// CleanupExpiredSessions removes expired sessions
	CleanupExpiredSessions(ctx context.Context) (*CleanupResult, error)
	
	// GetSessionStats returns session management statistics
	GetSessionStats() (*SessionStatistics, error)
}

// DelegationManager handles permission delegation and temporary access
type DelegationManager interface {
	// DelegatePermission delegates permission from one user to another
	DelegatePermission(ctx context.Context, fromUserID, toUserID string, permission Permission, duration time.Duration) (*Delegation, error)
	
	// RevokeDelegation revokes previously granted delegation
	RevokeDelegation(ctx context.Context, delegationID string) error
	
	// GetUserDelegations gets all delegations for a user
	GetUserDelegations(ctx context.Context, userID string) ([]*Delegation, error)
	
	// GetActiveDelegations gets all active delegations in system
	GetActiveDelegations(ctx context.Context) ([]*Delegation, error)
	
	// ValidateDelegation validates delegation request
	ValidateDelegation(ctx context.Context, delegation *Delegation) (*DelegationValidation, error)
	
	// GetDelegationStats returns delegation statistics
	GetDelegationStats() (*DelegationStatistics, error)
}