from app.modules.agent.engine.orchestrator.models import OutputContract, RoutingMeta, Scenario, TaskConstraints, TaskSpec
from app.modules.agent.engine.orchestrator.template_registry import ScenarioTemplateRegistry


def _task(scenario: Scenario) -> TaskSpec:
    return TaskSpec(
        task_id="t1",
        dialog_session_id="d1",
        rag_session_id="r1",
        mode="auto",
        user_message="run scenario",
        scenario=scenario,
        routing=RoutingMeta(domain_id="project", process_id="qa", confidence=0.9, reason="test"),
        constraints=TaskConstraints(
            allow_writes=scenario in {Scenario.DOCS_FROM_ANALYTICS, Scenario.TARGETED_EDIT, Scenario.GHERKIN_MODEL}
        ),
        output_contract=OutputContract(result_type="answer"),
        metadata={"rag_context": "ctx", "confluence_context": "", "files_map": {}},
    )


def test_template_registry_has_multi_step_review_docs_edit_gherkin() -> None:
    registry = ScenarioTemplateRegistry()

    review_steps = [step.step_id for step in registry.build(_task(Scenario.ANALYTICS_REVIEW)).steps]
    docs_steps = [step.step_id for step in registry.build(_task(Scenario.DOCS_FROM_ANALYTICS)).steps]
    edit_steps = [step.step_id for step in registry.build(_task(Scenario.TARGETED_EDIT)).steps]
    gherkin_steps = [step.step_id for step in registry.build(_task(Scenario.GHERKIN_MODEL)).steps]

    assert "structural_check" in review_steps and "compose_review_report" in review_steps
    assert "extract_change_intents" in docs_steps and "build_changeset" in docs_steps
    assert "resolve_target" in edit_steps and "finalize_changeset" in edit_steps
    assert "generate_gherkin_bundle" in gherkin_steps and "validate_coverage" in gherkin_steps

    assert len(review_steps) >= 7
    assert len(docs_steps) >= 9
    assert len(edit_steps) >= 7
    assert len(gherkin_steps) >= 8


def test_template_registry_adds_code_explain_pack_step_for_project_explain() -> None:
    registry = ScenarioTemplateRegistry()

    steps = [step.step_id for step in registry.build(_task(Scenario.EXPLAIN_PART)).steps]

    assert "code_explain_pack_step" in steps
    assert steps.index("code_explain_pack_step") > steps.index("context_retrieval")
    assert steps.index("code_explain_pack_step") < steps.index("context_analysis")
