"""Tests for manifest.json existence and schema after milco run."""

import json
from milco.cli import main
from milco.core.manifest import MANIFEST_SCHEMA_VERSION, ARTIFACT_NAMES


def _write_contract(tmp_path, confirm=False):
    contract = tmp_path / "TASK_CONTRACT.md"
    text = (
        "# Task Contract\n\n"
        "## Goal\n\nTest.\n\n"
        "## Scope\n\nTest.\n\n"
        "## Out of scope\n\nNone.\n\n"
        "## Success Criteria\n\nPass.\n\n"
        "## Constraints\n\nNone.\n\n"
        "## Approvals required\n\n"
    )
    if confirm:
        text += "CONFIRM APPLY\n\n"
    else:
        text += "None.\n\n"
    text += "## Notes\n\nNone.\n"
    contract.write_text(text, encoding="utf-8")
    return contract


def test_manifest_exists_after_dry_run(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "m-schema"])

    manifest_path = tmp_path / "runs" / "m-schema" / "manifest.json"
    assert manifest_path.exists()


def test_manifest_schema_version(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "m-ver"])

    data = json.loads(
        (tmp_path / "runs" / "m-ver" / "manifest.json").read_text(encoding="utf-8")
    )
    assert data["schema_version"] == "1.0"
    assert data["schema_version"] == MANIFEST_SCHEMA_VERSION


def test_manifest_required_keys(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "m-keys"])

    data = json.loads(
        (tmp_path / "runs" / "m-keys" / "manifest.json").read_text(encoding="utf-8")
    )
    required = [
        "schema_version",
        "run_id",
        "mode",
        "command",
        "timestamps",
        "repo",
        "artifacts",
        "outcome",
        "notes",
    ]
    for key in required:
        assert key in data, f"Missing top-level key: {key}"

    assert "started_at" in data["timestamps"]
    assert "finished_at" in data["timestamps"]
    assert "decision" in data["outcome"]
    assert "exit_code" in data["outcome"]
    assert "git_available" in data["repo"]


def test_manifest_artifacts_all_six(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "m-arts"])

    data = json.loads(
        (tmp_path / "runs" / "m-arts" / "manifest.json").read_text(encoding="utf-8")
    )
    for name in ARTIFACT_NAMES:
        assert name in data["artifacts"], f"Missing artifact entry: {name}"
        entry = data["artifacts"][name]
        assert "path" in entry
        assert "sha256" in entry
        assert "bytes" in entry


def test_manifest_dry_run_mode(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "m-mode"])

    data = json.loads(
        (tmp_path / "runs" / "m-mode" / "manifest.json").read_text(encoding="utf-8")
    )
    assert data["mode"] == "dry_run"
    assert data["outcome"]["decision"] == "PASS"
    assert data["outcome"]["exit_code"] == 0
