"""
cortex/core/retrieval_policy_routing.py — Task-mode policy application.

Extracted from retrieval_pipeline.py (#968 — SRP compliance, <500L target).
Implements the task-mode routing logic from #362 / #608.
"""

from __future__ import annotations

import logging
from copy import copy
from typing import TYPE_CHECKING, Optional, Tuple

if TYPE_CHECKING:
    from cortex.config import CortexConfig

from cortex.core.retrieval_types import RetrievalConstraints

logger = logging.getLogger(__name__)


def apply_task_mode_policy(
    config: "CortexConfig",
    query: str,
    task_mode_context: Optional[str],
    constraints: RetrievalConstraints,
) -> Tuple[bool, bool, RetrievalConstraints]:
    """Apply task-mode policy routing (#362 / #608).

    Returns ``(skip_working_memory, policy_set_top_k, constraints)``.
    Constraints may be a copy if top_k was overridden by the policy.
    """
    skip_wm = False
    set_top_k = False
    if task_mode_context is None:
        return skip_wm, set_top_k, constraints
    try:
        from cortex.core.task_mode import TaskModeClassifier, TaskMode
        from cortex.core.retrieval_policy import (
            CH_WORKING_MEMORY as _CH_WM, PolicyEngine,
        )
        if not getattr(config, "retrieval_policy_enabled", True):
            return skip_wm, set_top_k, constraints
        _default_mode_str = getattr(
            config, "retrieval_policy_default_mode", "recall_history",
        )
        try:
            _default_mode = TaskMode(_default_mode_str)
        except ValueError:
            _default_mode = TaskMode.RECALL_HISTORY
        classifier = TaskModeClassifier(default_mode=_default_mode)
        mode_result = classifier.classify(query, context=task_mode_context)
        engine = PolicyEngine(config=config)
        active_policy = engine.get_policy(mode_result)
        logger.debug(
            "retrieve: task_mode=%s confidence=%.3f policy=%s",
            mode_result.mode.value, mode_result.confidence,
            active_policy.description,
        )
        if constraints.top_k == 20:
            constraints = copy(constraints)
            constraints.top_k = active_policy.total_max_results
            set_top_k = True
        _wm_ch = active_policy.channels.get(_CH_WM)
        if _wm_ch is not None and not _wm_ch.enabled:
            skip_wm = True
    except Exception:
        logger.debug("retrieve: task-mode policy routing failed", exc_info=True)
    return skip_wm, set_top_k, constraints
