"""cortex/types/enums.py — Cortex enumerations."""

from __future__ import annotations

from enum import Enum


# ---------------------------------------------------------------------------
# Cortex deployment tier
# ---------------------------------------------------------------------------

class CortexTier(str, Enum):
    """Deployment tier for Cortex feature-flagging.

    LITE  — entry-level tier (default); limited feature set.
    FULL  — advanced tier; all features enabled.

    Used to gate functionality throughout the codebase via is_full_tier().
    """

    LITE = "lite"
    FULL = "full"


# ---------------------------------------------------------------------------
# Token Budget types (M9)
# ---------------------------------------------------------------------------

class MemoryLayer(str, Enum):
    """Priority-ordered memory layers for budget allocation.

    Order determines injection priority:
      CORNERSTONE (highest) → SESSION → SEMANTIC → PROCEDURAL (lowest)
    When budget is exceeded, lowest-priority layers are truncated first.
    """

    CORNERSTONE = "cornerstone"   # Identity-forming memories — always reserved
    SESSION = "session"           # Recent conversational context
    SEMANTIC = "semantic"         # Long-term factual/semantic memories
    PROCEDURAL = "procedural"     # How-to knowledge, procedures

    # Priority order: lower number = higher priority (truncated last)
    @property
    def priority(self) -> int:
        _priority = {
            MemoryLayer.CORNERSTONE: 0,
            MemoryLayer.SESSION: 1,
            MemoryLayer.SEMANTIC: 2,
            MemoryLayer.PROCEDURAL: 3,
        }
        return _priority[self]

    @classmethod
    def by_priority(cls) -> list["MemoryLayer"]:
        """Return layers ordered from highest to lowest priority."""
        return sorted(cls, key=lambda l: l.priority)

    @classmethod
    def truncation_order(cls) -> list["MemoryLayer"]:
        """Return layers ordered from lowest to highest priority (truncate first)."""
        return sorted(cls, key=lambda l: -l.priority)


# ---------------------------------------------------------------------------
# Bundle Compression types (Issue #373)
# ---------------------------------------------------------------------------

class CompressionLevel(int, Enum):
    """Bundle compression levels for memory injection.

    Three levels control how much an injected memory item is compressed
    when the token budget is under pressure.

    POINTER  (1) — Very short label; maximum compression.
    COMPACT  (2) — One bullet summary; moderate compression.
    EVIDENCE (3) — 2-4 bullets with brief support; minimal compression.

    Higher integer value = less compressed (more detail).
    Sorted ascending: POINTER < COMPACT < EVIDENCE.
    """

    POINTER = 1
    COMPACT = 2
    EVIDENCE = 3


class InjectionSlot(str, Enum):
    """Priority-ordered memory injection slots for slot-based budget allocation.

    Maps to the 6 memory slot priorities defined in Issue #374.
    Priority order: lower number = higher priority (allocated first, truncated last).

      TASK_CONTEXT    (0) — Active task context; highest priority
      BOOT_CONTEXT    (1) — Boot/session-start context; session-only
      OPEN_LOOPS      (2) — Open loops and commitments
      SEMANTIC_CLAIMS (3) — Relevant long-term semantic claims
      PROCEDURAL      (4) — Procedural / how-to memories
      EPISODIC        (5) — Episodic / historical context; lowest priority
    """

    TASK_CONTEXT = "task_context"
    BOOT_CONTEXT = "boot_context"
    OPEN_LOOPS = "open_loops"
    SEMANTIC_CLAIMS = "semantic_claims"
    PROCEDURAL = "procedural"
    EPISODIC = "episodic"

    @property
    def priority(self) -> int:
        _priority = {
            InjectionSlot.TASK_CONTEXT: 0,
            InjectionSlot.BOOT_CONTEXT: 1,
            InjectionSlot.OPEN_LOOPS: 2,
            InjectionSlot.SEMANTIC_CLAIMS: 3,
            InjectionSlot.PROCEDURAL: 4,
            InjectionSlot.EPISODIC: 5,
        }
        return _priority[self]

    @classmethod
    def by_priority(cls) -> list["InjectionSlot"]:
        """Return slots ordered from highest to lowest priority."""
        return sorted(cls, key=lambda s: s.priority)

    @classmethod
    def default_priority_names(cls) -> list[str]:
        """Return slot value strings in default priority order."""
        return [s.value for s in cls.by_priority()]
