// Package security provides shared security types and constants for BZZZ
// This package contains common security definitions that are used by both
// the crypto and slurp/roles packages to avoid circular dependencies.

package security

import "fmt"

// AccessLevel defines the security clearance levels for role-based encryption.
// These levels determine what level of sensitive information a user or role can access.
type AccessLevel int

const (
	// Public - Information accessible to all users
	AccessLevelPublic AccessLevel = iota
	
	// Internal - Information restricted to internal users
	AccessLevelInternal
	
	// Confidential - Information requiring confidential clearance
	AccessLevelConfidential
	
	// Secret - Information requiring secret clearance
	AccessLevelSecret
	
	// TopSecret - Information requiring top secret clearance
	AccessLevelTopSecret
)

// String returns the string representation of the access level
func (al AccessLevel) String() string {
	switch al {
	case AccessLevelPublic:
		return "public"
	case AccessLevelInternal:
		return "internal"
	case AccessLevelConfidential:
		return "confidential"
	case AccessLevelSecret:
		return "secret"
	case AccessLevelTopSecret:
		return "top-secret"
	default:
		return "unknown"
	}
}

// MarshalJSON implements json.Marshaler
func (al AccessLevel) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, al.String())), nil
}

// UnmarshalJSON implements json.Unmarshaler
func (al *AccessLevel) UnmarshalJSON(data []byte) error {
	str := string(data)
	str = str[1 : len(str)-1] // Remove quotes
	
	switch str {
	case "public":
		*al = AccessLevelPublic
	case "internal":
		*al = AccessLevelInternal
	case "confidential":
		*al = AccessLevelConfidential
	case "secret":
		*al = AccessLevelSecret
	case "top-secret":
		*al = AccessLevelTopSecret
	default:
		return fmt.Errorf("unknown access level: %s", str)
	}
	
	return nil
}

// CanAccess returns true if this access level can access the target level
func (al AccessLevel) CanAccess(target AccessLevel) bool {
	return al >= target
}

// IsValid returns true if the access level is valid
func (al AccessLevel) IsValid() bool {
	return al >= AccessLevelPublic && al <= AccessLevelTopSecret
}

// GetRequiredLevel returns the minimum access level required for a given sensitivity
func GetRequiredLevel(sensitivity string) AccessLevel {
	switch sensitivity {
	case "public":
		return AccessLevelPublic
	case "internal":
		return AccessLevelInternal
	case "confidential":
		return AccessLevelConfidential
	case "secret":
		return AccessLevelSecret
	case "top-secret":
		return AccessLevelTopSecret
	default:
		return AccessLevelInternal // Default to internal for unknown
	}
}