"""
tests/test_platform_priority_digest.py

Tests for platform_priority_digest.py:
  - band_counts in output
  - investment_priority_list: only services with requires_arch_review + risk elevated
  - action recommendations generated
  - markdown contains expected sections
  - JSON output structure
  - file writing (mocked)
  - followup creation callback
"""
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../services/router"))

import json
import pytest
from unittest.mock import patch, MagicMock
from platform_priority_digest import (
    weekly_platform_digest,
    _build_priority_actions,
    _build_markdown,
    _clamp,
)
from architecture_pressure import _builtin_pressure_defaults, _reload_pressure_policy


@pytest.fixture(autouse=True)
def reset_policy():
    _reload_pressure_policy()
    yield
    _reload_pressure_policy()


@pytest.fixture
def policy():
    p = _builtin_pressure_defaults()
    p["digest"]["output_dir"] = "/tmp/test_platform_digest"
    return p


def _pressure_report(
    service: str,
    score: int,
    band: str,
    requires_review: bool = False,
    components: dict = None,
) -> dict:
    return {
        "service": service,
        "env": "prod",
        "lookback_days": 30,
        "score": score,
        "band": band,
        "components": components or {
            "recurrence_high_30d": 0, "recurrence_warn_30d": 0,
            "regressions_30d": 0, "escalations_30d": 0,
            "followups_created_30d": 0, "followups_overdue": 0,
            "drift_failures_30d": 0, "dependency_high_30d": 0,
        },
        "signals_summary": [f"Signal for {service}"],
        "requires_arch_review": requires_review,
        "computed_at": "2026-01-01T00:00:00",
    }


class TestClamp:
    def test_short_text_unchanged(self):
        assert _clamp("hello", 100) == "hello"

    def test_long_text_truncated(self):
        text = "a" * 200
        result = _clamp(text, 100)
        assert len(result) <= 100
        assert result.endswith("…")


class TestBuildPriorityActions:
    def test_arch_review_action_generated(self, policy):
        reports = [_pressure_report("gateway", 80, "critical", requires_review=True)]
        actions = _build_priority_actions(reports)
        assert any("architecture review" in a.lower() for a in actions)

    def test_freeze_features_for_critical_plus_high_risk(self, policy):
        reports = [_pressure_report("svc", 90, "critical", requires_review=True)]
        risk_reports = {"svc": {"band": "high", "score": 80}}
        actions = _build_priority_actions(reports, risk_reports)
        assert any("Freeze" in a for a in actions)

    def test_reduce_backlog_for_overdue(self, policy):
        reports = [_pressure_report(
            "svc", 50, "medium",
            components={
                "recurrence_high_30d": 0, "recurrence_warn_30d": 0,
                "regressions_30d": 0, "escalations_30d": 0,
                "followups_created_30d": 0, "followups_overdue": 3,
                "drift_failures_30d": 0, "dependency_high_30d": 0,
            },
        )]
        actions = _build_priority_actions(reports)
        assert any("backlog" in a.lower() for a in actions)

    def test_no_actions_for_low_pressure(self, policy):
        reports = [_pressure_report("svc", 5, "low")]
        actions = _build_priority_actions(reports)
        assert len(actions) == 0


class TestBuildMarkdown:
    def test_contains_header(self):
        md = _build_markdown(
            week_str="2026-W08", env="prod",
            pressure_reports=[],
            investment_list=[],
            actions=[],
            band_counts={"critical": 0, "high": 0, "medium": 0, "low": 0},
        )
        assert "Platform Priority Digest" in md
        assert "2026-W08" in md

    def test_critical_section_present(self):
        reports = [_pressure_report("gateway", 90, "critical", requires_review=True)]
        md = _build_markdown(
            "2026-W08", "prod", reports, [], [], {"critical": 1, "high": 0, "medium": 0, "low": 0}
        )
        assert "Critical Structural Pressure" in md
        assert "gateway" in md

    def test_investment_list_section(self):
        inv = [{"service": "svc", "pressure_score": 80, "pressure_band": "critical",
                "risk_score": 70, "risk_band": "high", "risk_delta_24h": 10}]
        md = _build_markdown(
            "2026-W08", "prod", [], inv, [], {"critical": 0, "high": 0, "medium": 0, "low": 0}
        )
        assert "Investment Priority List" in md
        assert "svc" in md

    def test_action_recommendations_section(self):
        actions = ["📋 **Schedule architecture review**: 'svc' pressure=80 (critical)"]
        md = _build_markdown(
            "2026-W08", "prod", [], [], actions, {"critical": 0, "high": 0, "medium": 0, "low": 0}
        )
        assert "Action Recommendations" in md
        assert "Schedule architecture review" in md

    def test_arch_review_flag_shown(self):
        reports = [_pressure_report("router", 75, "critical", requires_review=True)]
        md = _build_markdown(
            "2026-W08", "prod", reports, [], [], {"critical": 1, "high": 0, "medium": 0, "low": 0}
        )
        assert "ARCH REVIEW REQUIRED" in md


class TestWeeklyPlatformDigest:
    def test_empty_reports_returns_digest(self, policy):
        result = weekly_platform_digest(
            "prod",
            pressure_reports=[],
            policy=policy,
            write_files=False,
        )
        assert "markdown" in result
        assert "json_data" in result
        assert result["band_counts"] == {"critical": 0, "high": 0, "medium": 0, "low": 0}

    def test_band_counts_accurate(self, policy):
        reports = [
            _pressure_report("svc1", 90, "critical", requires_review=True),
            _pressure_report("svc2", 60, "high"),
            _pressure_report("svc3", 30, "medium"),
        ]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy, write_files=False
        )
        counts = result["band_counts"]
        assert counts["critical"] == 1
        assert counts["high"] == 1
        assert counts["medium"] == 1

    def test_investment_list_only_review_plus_risk_elevated(self, policy):
        reports = [
            _pressure_report("svc_review_high_risk", 80, "critical", requires_review=True),
            _pressure_report("svc_review_low_risk", 80, "critical", requires_review=True),
            _pressure_report("svc_no_review", 30, "medium", requires_review=False),
        ]
        risk_reports = {
            "svc_review_high_risk": {"band": "high", "score": 75,
                                      "trend": {"delta_24h": 5}},
            "svc_review_low_risk": {"band": "low", "score": 10,
                                     "trend": {"delta_24h": None}},
        }
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, risk_reports=risk_reports,
            policy=policy, write_files=False,
        )
        inv = result["json_data"]["investment_priority_list"]
        inv_services = [i["service"] for i in inv]
        assert "svc_review_high_risk" in inv_services
        assert "svc_no_review" not in inv_services
        # svc_review_low_risk: low band + None delta → excluded
        assert "svc_review_low_risk" not in inv_services

    def test_markdown_has_critical_section(self, policy):
        reports = [_pressure_report("gateway", 90, "critical", requires_review=True)]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy, write_files=False
        )
        assert "Critical Structural Pressure" in result["markdown"]

    def test_json_structure(self, policy):
        reports = [_pressure_report("svc", 40, "medium")]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy, write_files=False
        )
        jd = result["json_data"]
        assert "week" in jd
        assert "band_counts" in jd
        assert "top_pressure_services" in jd
        assert "investment_priority_list" in jd
        assert "actions" in jd

    def test_files_written_to_disk(self, policy, tmp_path):
        policy["digest"]["output_dir"] = str(tmp_path)
        reports = [_pressure_report("svc", 40, "medium")]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports,
            policy=policy, write_files=True,
        )
        assert len(result["files_written"]) == 2
        for f in result["files_written"]:
            assert os.path.exists(f)

    def test_followup_creation_called(self, policy):
        """Auto followup should be attempted for services requiring review."""
        reports = [_pressure_report("svc_big", 90, "critical", requires_review=True)]
        created = []

        class FakeIncidentStore:
            def list_incidents(self, filters, limit=50):
                return [{"id": "inc_001", "status": "open",
                          "started_at": "2026-01-01T00:00:00", "service": "svc_big"}]
            def get_events(self, inc_id, limit=100):
                return []
            def create_incident(self, data):
                return {"id": "inc_syn_001", **data}

        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy,
            write_files=False, auto_followup=True,
            incident_store=FakeIncidentStore(),
        )
        # Should have attempted (created or skipped) for svc_big
        assert "followups_created" in result

    def test_no_followup_when_auto_followup_false(self, policy):
        reports = [_pressure_report("svc", 90, "critical", requires_review=True)]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy,
            write_files=False, auto_followup=False,
        )
        assert result["followups_created"] == []

    def test_top_n_respected(self, policy):
        reports = [_pressure_report(f"svc_{i}", 50 - i, "medium") for i in range(20)]
        result = weekly_platform_digest(
            "prod", pressure_reports=reports, policy=policy,
            write_files=False,
        )
        assert len(result["json_data"]["top_pressure_services"]) <= 10

    def test_week_str_in_output(self, policy):
        result = weekly_platform_digest(
            "prod", pressure_reports=[], policy=policy,
            week_str="2026-W05", write_files=False,
        )
        assert result["week"] == "2026-W05"
        assert "2026-W05" in result["json_data"]["week"]
