from __future__ import annotations

import hashlib
from pathlib import Path

import pytest

from repository_rename_workplan import (
    WorkplanGenerationError,
    build_generation_snapshot,
    content_checksum,
    default_output_path,
    render_workplan,
    write_workplan_exclusive,
)
from scripts.quality_debt import collect as collect_quality_debt
from scripts.validate_repo_adr import validate


REPO_ID = "fda8ad85-a7d7-4055-8f21-902a533e59df"


def _repo(path: str | None = None, **extra) -> dict:
    return {
        "id": REPO_ID,
        "slug": "flex-auth",
        "canonical_slug": "flex-auth",
        "domain_slug": "infotech",
        "local_path": path,
        "host_paths": {},
        "aliases": [],
        **extra,
    }


def _preflight(**extra) -> dict:
    report = {
        "schema_version": "state-hub.repository-rename-preflight.v1",
        "repo_id": REPO_ID,
        "old_slug": "flex-auth",
        "new_slug": "access-engine",
        "safe_to_apply": True,
        "blockers": [],
        "warnings": [],
        "report_checksum": "a" * 64,
        "preflight_token": "must-never-appear-in-workplan",
        "preflighted_at": "2026-08-29T08:00:00Z",
        "current": {
            "statehub": {
                "repo_id": REPO_ID,
                "local_path": None,
                "host_paths": {},
            },
            "forge_identity": {
                "verification_state": "verified",
                "forge_repository_id": 42,
                "forge_owner": "coulomb",
            },
            "forge_available": True,
            "forge": {
                "repository_id": 42,
                "default_branch": "main",
                "head_commit": "b" * 40,
            },
        },
        "active_work": {"workplans": [], "tasks": []},
        "affected": {"external_handoffs": []},
    }
    report.update(extra)
    return report


def _workplans() -> list[dict]:
    return [
        {
            "id": "11111111-1111-4111-8111-111111111111",
            "slug": "flex-wp-0017",
            "status": "active",
            "backing_filename": "FLEX-WP-0017-action-contract.md",
        },
        {
            "id": "22222222-2222-4222-8222-222222222222",
            "slug": "flex-wp-0018",
            "status": "archived",
            "backing_filename": "260828-FLEX-WP-0018-inbound-corrections.md",
            "backing_archived": True,
        },
    ]


def _repo_root(tmp_path: Path) -> Path:
    root = tmp_path / "flex-auth"
    root.mkdir()
    (root / "AGENTS.md").write_text("**Workplan prefix:** `FLEX-WP-`\n")
    return root


def test_flex_auth_snapshot_is_deterministic_and_complete(tmp_path):
    root = _repo_root(tmp_path)
    report = _preflight(
        warnings=[
            {
                "code": "active_work_present",
                "message": "coordinate NetKingdom security-stack work",
                "workplan_count": 1,
            }
        ],
        affected={
            "external_handoffs": [
                "fabric-graph-projections",
                "interface-change-consumers",
            ]
        },
        active_work={
            "workplans": [
                {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "slug": "FLEX-WP-0017",
                    "status": "active",
                }
            ],
            "tasks": [
                {
                    "id": "44444444-4444-4444-8444-444444444444",
                    "record_id": "FLEX-WP-0017-T05",
                    "status": "progress",
                }
            ],
        },
    )
    snapshot = build_generation_snapshot(
        repo=_repo(str(root), aliases=["flexauth-legacy"]),
        preflight=report,
        workplans=_workplans(),
    )
    first = render_workplan(snapshot, owner="codex")
    second = render_workplan(snapshot, owner="codex")

    assert first == second
    assert content_checksum(first) == hashlib.sha256(first.encode()).hexdigest()
    assert snapshot.prefix == "FLEX-WP"
    assert snapshot.workplan_id == "FLEX-WP-0019"
    assert first.count("```task\n") == 11
    assert "id: FLEX-WP-0019-T06\nstatus: wait" in first
    assert "id: FLEX-WP-0019-T11\nstatus: wait" in first
    assert "state_hub_workstream_id:" not in first
    assert "state_hub_task_id:" not in first
    assert "must-never-appear-in-workplan" not in first
    assert "`active_work_present`" in first
    assert "`fabric-graph-projections`" in first
    assert "`interface-change-consumers`" in first
    assert "FLEX_AUTH_*" in first
    assert "NetKingdom policy consumers" in first
    assert "flexauth-legacy" in first
    assert "| Credential-route catalog | `ops-warden` |" in first
    assert "only that repository closes" in first


def test_generated_snapshot_passes_parser_and_quality_debt(tmp_path):
    root = _repo_root(tmp_path)
    snapshot = build_generation_snapshot(
        repo=_repo(str(root)),
        preflight=_preflight(),
        workplans=_workplans(),
    )
    content = render_workplan(snapshot, owner="codex")
    output = default_output_path(snapshot)
    write_workplan_exclusive(output, content)

    report = validate(root, skip_api=True)
    assert report.failures == []
    assert collect_quality_debt(
        root, api_base=None, include_hub_intakes=False
    ) == []
    assert output.name.startswith("FLEX-WP-0019-")


def test_snapshot_counts_archived_workplans_when_allocating_id(tmp_path):
    root = _repo_root(tmp_path)
    snapshot = build_generation_snapshot(
        repo=_repo(str(root)),
        preflight=_preflight(),
        workplans=[
            {
                "slug": "flex-wp-0004",
                "status": "active",
                "backing_filename": "FLEX-WP-0004-live.md",
            },
            {
                "slug": "flex-wp-0099",
                "status": "archived",
                "backing_filename": "260101-FLEX-WP-0099-old.md",
                "backing_archived": True,
            },
        ],
    )
    assert snapshot.workplan_id == "FLEX-WP-0100"
    assert snapshot.archived_workplan_ids == ("FLEX-WP-0099",)


def test_snapshot_renders_active_work_and_private_forge_failure(tmp_path):
    root = _repo_root(tmp_path)
    report = _preflight(
        safe_to_apply=False,
        blockers=[
            {
                "code": "forge_unreadable",
                "message": "private repository could not be inspected",
            }
        ],
        current={
            "statehub": {"repo_id": REPO_ID, "host_paths": {}},
            "forge_identity": {"verification_state": "unverified"},
            "forge_available": False,
            "forge": None,
        },
        active_work={
            "workplans": [
                {"id": "active-uuid", "slug": "FLEX-WP-0017", "status": "active"}
            ],
            "tasks": [],
        },
    )
    snapshot = build_generation_snapshot(
        repo=_repo(str(root)), preflight=report, workplans=_workplans()
    )
    rendered = render_workplan(snapshot, owner="codex")
    assert "status: proposed" in rendered
    assert "`forge_unreadable`" in rendered
    assert "`forge-identity-unverified`" in rendered
    assert "`forge-repository-unreadable`" in rendered
    assert "workplan `FLEX-WP-0017` / `active-uuid` is `active`" in rendered
    assert "id: FLEX-WP-0019-T06\nstatus: wait" in rendered


def test_snapshot_supports_missing_local_path_from_indexed_workplans(tmp_path):
    missing = tmp_path / "not-mounted"
    snapshot = build_generation_snapshot(
        repo=_repo(str(missing)),
        preflight=_preflight(),
        workplans=_workplans(),
    )
    rendered = render_workplan(snapshot, owner="codex")
    assert snapshot.prefix == "FLEX-WP"
    assert snapshot.path_available is False
    assert "`local-path-unavailable`" in rendered
    with pytest.raises(WorkplanGenerationError) as exc:
        default_output_path(snapshot)
    assert exc.value.code == "repository_path_unavailable"


def test_snapshot_preserves_old_alias_context(tmp_path):
    root = _repo_root(tmp_path)
    snapshot = build_generation_snapshot(
        repo=_repo(str(root), aliases=["old-flex", "flex-auth"]),
        preflight=_preflight(),
        workplans=_workplans(),
    )
    rendered = render_workplan(snapshot, owner="codex")
    assert 'protected/current aliases: `["flex-auth", "old-flex"]`' in rendered
    assert "Retain the protected `flex-auth` alias" in rendered


def test_existing_uuid_fields_are_untouched_and_not_copied_to_new_plan(tmp_path):
    root = _repo_root(tmp_path)
    workplans = root / "workplans"
    workplans.mkdir()
    existing = workplans / "FLEX-WP-0001-existing.md"
    original = """---
id: FLEX-WP-0001
type: workplan
title: Existing
domain: infotech
status: active
owner: codex
created: "2026-01-01"
state_hub_workstream_id: "55555555-5555-4555-8555-555555555555"
---
"""
    existing.write_text(original)
    snapshot = build_generation_snapshot(
        repo=_repo(str(root)), preflight=_preflight(), workplans=[]
    )
    rendered = render_workplan(snapshot, owner="codex")
    assert existing.read_text() == original
    assert "55555555-5555-4555-8555-555555555555" not in rendered
    assert "state_hub_workstream_id:" not in rendered


def test_exclusive_writer_refuses_existing_output(tmp_path):
    output = tmp_path / "existing.md"
    output.write_text("operator content\n")
    with pytest.raises(WorkplanGenerationError) as exc:
        write_workplan_exclusive(output, "replacement\n")
    assert exc.value.code == "output_exists"
    assert output.read_text() == "operator content\n"


def test_prefix_is_never_derived_from_new_slug(tmp_path):
    root = tmp_path / "repo"
    root.mkdir()
    snapshot = build_generation_snapshot(
        repo=_repo(str(root)),
        preflight=_preflight(),
        workplans=_workplans(),
    )
    assert snapshot.prefix == "FLEX-WP"
    assert not snapshot.workplan_id.startswith("ACCESS-ENGINE")


def test_ambiguous_indexed_prefixes_fail_closed(tmp_path):
    root = tmp_path / "repo"
    root.mkdir()
    with pytest.raises(WorkplanGenerationError) as exc:
        build_generation_snapshot(
            repo=_repo(str(root)),
            preflight=_preflight(),
            workplans=[
                {"slug": "flex-wp-0001"},
                {"slug": "other-wp-0001"},
            ],
        )
    assert exc.value.code == "workplan_prefix_ambiguous"
