"""Robot Framework helper for ACMS pipeline Phase 3 integration tests.

Provides a CLI-style interface for Robot to invoke Phase 3 pipeline
components and verify the results.  Exit code 0 = success, 1 = failure.

Usage:
    python robot/helper_acms_pipeline_phase3.py orderer-basic
    python robot/helper_acms_pipeline_phase3.py preamble-generate
    python robot/helper_acms_pipeline_phase3.py arce-strategy
    python robot/helper_acms_pipeline_phase3.py temporal-strategy
    python robot/helper_acms_pipeline_phase3.py plan-decision-strategy
    python robot/helper_acms_pipeline_phase3.py pipeline-integration
"""

from __future__ import annotations

import sys
from collections.abc import Callable
from pathlib import Path

_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

from cleveragents.application.services.acms_advanced_strategies import (  # noqa: E402
    ArceStrategy,
    PlanDecisionContextStrategy,
    TemporalArchaeologyStrategy,
)
from cleveragents.application.services.acms_phase3 import (  # noqa: E402
    ProvenancePreambleGenerator,
    RelevanceCoherenceOrderer,
)
from cleveragents.application.services.acms_service import ACMSPipeline  # noqa: E402
from cleveragents.domain.models.core.context_fragment import (  # noqa: E402
    ContextBudget,
    ContextFragment,
    FragmentProvenance,
)

_DEFAULT_PROV = FragmentProvenance(resource_uri="test://robot-phase3")
_PLAN_ID = "01JQTESTPN00000000000000DD"


def _frag(
    uko_node: str = "test://default",
    content: str = "test content",
    score: float = 0.5,
    tokens: int = 10,
    depth: int = 0,
    tier: str = "warm",
    strategy_source: str = "",
) -> ContextFragment:
    return ContextFragment(
        uko_node=uko_node,
        content=content,
        relevance_score=score,
        token_count=tokens,
        detail_depth=depth,
        tier=tier,
        strategy_source=strategy_source,
        provenance=_DEFAULT_PROV,
    )


# ---------------------------------------------------------------------------
# Test commands
# ---------------------------------------------------------------------------


def _test_orderer_basic() -> None:
    """Test RelevanceCoherenceOrderer groups and orders fragments."""
    orderer = RelevanceCoherenceOrderer()
    frags = [
        _frag("project://app/io.py", "io module", 0.9, 20, 3),
        _frag("project://app/main.py", "main entry", 0.5, 15, 3),
        _frag("project://lib/util.py", "utility", 0.7, 25, 3),
        _frag("project://app/net.py", "network", 0.8, 10, 3),
    ]
    result = list(orderer.order(frags))
    assert len(result) == 4, f"Expected 4, got {len(result)}"
    # First fragment should be from the highest-relevance group
    assert result[0].relevance_score == 0.9
    print("phase3-orderer-ok")


def _test_preamble_generate() -> None:
    """Test ProvenancePreambleGenerator produces structured preamble."""
    gen = ProvenancePreambleGenerator()
    frags = [
        _frag(
            "project://app/main.py",
            "hello",
            0.8,
            100,
            3,
            strategy_source="relevance",
        ),
        _frag(
            "project://app/io.py",
            "world",
            0.6,
            50,
            5,
            strategy_source="arce",
        ),
    ]
    preamble = gen.generate(frags)
    assert preamble is not None
    assert "Strategy Contributions" in preamble
    assert "relevance" in preamble
    assert "arce" in preamble
    assert "Confidence" in preamble

    # Empty list returns None
    assert gen.generate([]) is None
    print("phase3-preamble-ok")


def _test_arce_strategy() -> None:
    """Test ArceStrategy iterative refinement."""
    strategy = ArceStrategy(max_iterations=3)
    assert strategy.name == "arce"
    assert strategy.can_handle({}) == 0.95
    assert strategy.capabilities.supports_semantic_search

    frags = [
        _frag("project://app/io.py", "async IO handler", 0.7, 20, 5),
        _frag("project://app/main.py", "main application", 0.5, 15, 3),
    ]
    budget = ContextBudget(max_tokens=1000, reserved_tokens=0)
    result = list(strategy.assemble(frags, budget))
    assert len(result) > 0
    total = sum(f.token_count for f in result)
    assert total <= 1000

    # Empty input
    assert list(strategy.assemble([], budget)) == []
    print("phase3-arce-ok")


def _test_temporal_strategy() -> None:
    """Test TemporalArchaeologyStrategy cold-tier preference."""
    strategy = TemporalArchaeologyStrategy()
    assert strategy.name == "temporal-archaeology"
    assert strategy.can_handle({}) == 0.5

    frags = [
        _frag("project://app/old.py", "archived", 0.5, 20, 3, tier="cold"),
        _frag("project://app/new.py", "recent", 0.9, 15, 3, tier="hot"),
    ]
    budget = ContextBudget(max_tokens=1000, reserved_tokens=0)
    result = list(strategy.assemble(frags, budget))
    assert len(result) > 0
    # Cold-tier should be first
    assert result[0].tier == "cold"

    assert list(strategy.assemble([], budget)) == []
    print("phase3-temporal-ok")


def _test_plan_decision_strategy() -> None:
    """Test PlanDecisionContextStrategy warm/cold preference."""
    strategy = PlanDecisionContextStrategy()
    assert strategy.name == "plan-decision-context"
    assert strategy.can_handle({}) == 0.7

    frags = [
        _frag("project://app/plan.py", "decision", 0.7, 20, 3, tier="warm"),
        _frag("project://app/new.py", "new code", 0.9, 15, 3, tier="hot"),
    ]
    budget = ContextBudget(max_tokens=1000, reserved_tokens=0)
    result = list(strategy.assemble(frags, budget))
    assert len(result) > 0
    # Warm-tier should be first
    assert result[0].tier == "warm"

    assert list(strategy.assemble([], budget)) == []
    print("phase3-plan-decision-ok")


def _test_pipeline_integration() -> None:
    """Test Phase 3 components injected into ACMSPipeline."""
    pipeline = ACMSPipeline(
        orderer=RelevanceCoherenceOrderer(),
        preamble_generator=ProvenancePreambleGenerator(),
    )
    frags = [
        _frag("project://app/main.py", "hello", 0.8, 10, 3),
        _frag("project://lib/util.py", "world", 0.6, 15, 5),
    ]
    budget = ContextBudget(max_tokens=100000, reserved_tokens=0)
    payload = pipeline.assemble(
        plan_id=_PLAN_ID,
        fragments=frags,
        budget=budget,
    )
    assert len(payload.fragments) == 2
    assert payload.preamble is not None
    assert "Context Assembly Provenance" in payload.preamble
    print("phase3-pipeline-ok")


# ---------------------------------------------------------------------------
# Dispatcher
# ---------------------------------------------------------------------------

_TESTS: dict[str, Callable[[], None]] = {
    "orderer-basic": _test_orderer_basic,
    "preamble-generate": _test_preamble_generate,
    "arce-strategy": _test_arce_strategy,
    "temporal-strategy": _test_temporal_strategy,
    "plan-decision-strategy": _test_plan_decision_strategy,
    "pipeline-integration": _test_pipeline_integration,
}

if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] not in _TESTS:
        print(f"Usage: {sys.argv[0]} <{'|'.join(_TESTS)}>", file=sys.stderr)
        sys.exit(2)
    try:
        _TESTS[sys.argv[1]]()
    except Exception as exc:
        print(f"FAIL: {exc}", file=sys.stderr)
        import traceback

        traceback.print_exc()
        sys.exit(1)
