import json
from pathlib import Path


def _mk_factory_module(monkeypatch, tmp_path):
    from products import product_factory

    monkeypatch.setattr(product_factory, "ROOT", tmp_path)
    monkeypatch.setattr(product_factory, "EVENT_DIR", tmp_path / ".events")
    monkeypatch.setattr(product_factory, "PRODUCTS_DIR", tmp_path / "generated")
    monkeypatch.setattr(product_factory, "DASHBOARD", tmp_path / "DASHBOARD.md")
    monkeypatch.setattr(product_factory, "PLANS_DIR", tmp_path / "plans")
    monkeypatch.setattr(product_factory, "RECEIPTS_DIR", tmp_path / "receipts")
    monkeypatch.setattr(product_factory, "run_adw_pipeline", lambda product_id, zte=False: {"ok": True})
    return product_factory


def test_product_factory_creates_spec(tmp_path, monkeypatch):
    product_factory = _mk_factory_module(monkeypatch, tmp_path)

    result = product_factory.create_product("Agent powered support triage")

    assert result["product_id"] == "agent-powered-support-triage"
    assert (tmp_path / "generated" / result["product_id"] / "spec.json").exists()
    assert Path(result["plan"]).exists()
    assert Path(result["receipt"]).exists()

    spec = json.loads((tmp_path / "generated" / result["product_id"] / "spec.json").read_text())
    assert spec["living_plan"]["deploy_endpoint"] == "git-proxy:8099/deploy"
    assert spec["living_plan"]["rsi_decision"] == "healthy_but_autopatch_unproven"
    assert spec["living_plan"]["auto_patch_proven"] is False
    assert spec["living_plan"]["rsi_canary_recovery_evidence"] is True
    assert spec["living_plan"]["rsi_evidence_receipt"].endswith("rsi-proof-20260619T093724Z.md")
    assert spec["living_plan"]["local_rsi_evidence_receipt"].endswith("rsi-proof-20260619T093724Z.md")
    assert set(spec["living_plan"]["loop_engineering"]) == {
        "agent_loop",
        "verification_loop",
        "event_driven_loop",
        "hill_climbing_loop",
    }

    receipt = json.loads(Path(result["receipt"]).read_text())
    assert receipt["deploy_route"] == "git-proxy:8099/deploy"
    assert receipt["rsi_decision"] == "healthy_but_autopatch_unproven"
    assert receipt["auto_patch_proven"] is False
    assert receipt["rsi_canary_recovery_evidence"] is True
    assert receipt["rsi_evidence_receipt"].endswith("rsi-proof-20260619T093724Z.md")
    assert receipt["local_rsi_evidence_receipt"].endswith("rsi-proof-20260619T093724Z.md")
    assert receipt["loop_engineering"]["hill_climbing_loop"].startswith("skill_health")

    log = next((tmp_path / ".events").glob("*.jsonl"))
    events = [json.loads(line) for line in log.read_text().splitlines()]
    assert [e["kind"] for e in events] == [
        "idea_received",
        "product_spec_created",
        "plan_written",
        "adw_pipeline_started",
        "checks_run",
        "verifier_result",
        "deploy_action_requested",
        "outcome",
    ]
    checks = next(e for e in events if e["kind"] == "checks_run")
    assert checks["checks"] == ["plan", "build", "test", "review", "document", "ship"]
    assert checks["checks_ok"] is True
    assert checks["plan_id"] == "agent-powered-support-triage"
    assert checks["plan_ref"].endswith("plan.md")

    plan_event = next(e for e in events if e["kind"] == "plan_written")
    assert plan_event["plan_id"] == "agent-powered-support-triage"
    assert plan_event["plan_ref"].endswith("plan.md")

    dashboard = (tmp_path / "DASHBOARD.md").read_text()
    assert "## Last check" in dashboard
    assert "## Deploy readiness" in dashboard
    assert "git-proxy:8099/deploy" in dashboard
    assert "auto_patch_proven=false" in dashboard
    assert "rsi-proof-20260619T093724Z.md" in dashboard
    assert "## Loop engineering" in dashboard
    assert "Loop 4 hill-climbing" in dashboard
    assert "## Open risks" in dashboard


def test_product_factory_blocks_overwrite_when_exists(tmp_path, monkeypatch):
    product_factory = _mk_factory_module(monkeypatch, tmp_path)

    first = product_factory.create_product("Duplication safety check")

    existing_spec = Path(first["path"]) / "spec.json"
    stamp = existing_spec.stat().st_mtime

    assert first["product_id"] == "duplication-safety-check"
    assert existing_spec.exists()

    import pytest

    with pytest.raises(FileExistsError):
        product_factory.create_product("Duplication safety check")

    # same product still re-runs with explicit overwrite
    second = product_factory.create_product("Duplication safety check", overwrite=True)
    assert second["product_id"] == first["product_id"]
    assert second["plan"] != ""
    assert Path(second["plan"]).exists()
    assert Path(second["plan"]).resolve() == (tmp_path / "plans" / "duplication-safety-check" / "plan.md").resolve()
    assert existing_spec.stat().st_mtime >= stamp
