"""
orchestrator.py — Routes webhook events to the appropriate agent pipeline.

State → Pipeline mapping
────────────────────────
Active / In Progress / Approved  → test_cases  (Agent 1 for ADO, Agent 5 for Jira)
Resolved / Done / Closed         → gherkin_playwright (Agents 2 → 3 → 4)
"""
from __future__ import annotations

import asyncio
import logging
import os

from .models import Platform, PipelineResult, PipelineStage, WebhookEvent

# Re-export models so existing importers (webhook_bridge.py) continue to work.
__all__ = [
    "Platform", "PipelineResult", "PipelineStage", "WebhookEvent",
    "classify_state", "run_pipeline",
]

logger = logging.getLogger("stlc.orchestrator")

_ADO_TEST_CASE_STATES = frozenset({
    "active", "approved", "committed", "in progress", "in review", "ready for testing",
})
_ADO_FULL_PIPELINE_STATES = frozenset({
    "resolved", "done", "closed", "completed", "released",
})
_JIRA_TEST_CASE_STATES = frozenset({
    "in progress", "active", "in development", "in review",
    "ready for qa", "approved",
})
_JIRA_FULL_PIPELINE_STATES = frozenset({
    "resolved", "done", "closed", "completed", "released",
})
_SKIP_TYPES = frozenset({"epic", "test case", "test suite", "test plan"})


# ──────────────────────────────────────────────────────────────────────────────
# State classifier — routing logic only
# ──────────────────────────────────────────────────────────────────────────────

def classify_state(event: WebhookEvent) -> PipelineStage:
    wi_type = (event.work_item_type or "").lower()
    if wi_type in _SKIP_TYPES:
        return PipelineStage.SKIP

    # Explicit full-pipeline override takes priority over state-based routing.
    if (
        event.extra.get("pipeline") == "full"
        or os.environ.get("STLC_FULL_PIPELINE", "").lower() == "true"
    ):
        return PipelineStage.FULL

    state = (event.state or "").lower()
    if event.platform == Platform.ADO:
        if state in _ADO_TEST_CASE_STATES:
            return PipelineStage.TEST_CASES
        if state in _ADO_FULL_PIPELINE_STATES:
            return PipelineStage.GHERKIN_PLAYWRIGHT
    else:
        if state in _JIRA_TEST_CASE_STATES:
            return PipelineStage.TEST_CASES
        if state in _JIRA_FULL_PIPELINE_STATES:
            return PipelineStage.GHERKIN_PLAYWRIGHT

    return PipelineStage.SKIP


# ──────────────────────────────────────────────────────────────────────────────
# Entry point — delegates entirely to the appropriate pipeline module
# ──────────────────────────────────────────────────────────────────────────────

async def run_pipeline(event: WebhookEvent) -> PipelineResult:
    stage = classify_state(event)
    logger.info(
        "Pipeline stage: %s (platform=%s wi=%s state=%s)",
        stage, event.platform, event.work_item_id, event.state,
    )

    if stage == PipelineStage.SKIP:
        return PipelineResult(success=True, steps=["skipped"])

    if stage == PipelineStage.FULL:
        from .pipelines.full_pipeline import run
    elif stage == PipelineStage.TEST_CASES:
        if event.platform == Platform.ADO:
            from .pipelines.ado_test_cases import run
        else:
            from .pipelines.jira_test_cases import run
    else:
        from .pipelines.gherkin_playwright import run

    try:
        return await asyncio.wait_for(run(event), timeout=600)
    except asyncio.TimeoutError:
        return PipelineResult(
            success=False,
            steps=[f"{stage.value}: wi={event.work_item_id}"],
            error="Pipeline timed out after 600s",
        )
