#!/usr/bin/env python3
"""Create manual evidence templates for a 1C extension validation plan."""

from __future__ import annotations

import argparse
import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def load_json(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8-sig"))


def write_json(path: Path, data: dict[str, Any]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


def evidence_root(plan: dict[str, Any], override: Path | None = None) -> Path:
    if override:
        return override
    configured = ((plan.get("runner_config") or {}).get("evidence_root")) or ((plan.get("evidence") or {}).get("root"))
    if not configured:
        raise SystemExit("Validation plan has no evidence root.")
    return Path(str(configured))


def file_template(name: str, plan: dict[str, Any]) -> str:
    if name.endswith(".json"):
        payload: dict[str, Any] = {
            "schema": "onec_extension_validation_manual_evidence.v1",
            "status": "pending",
            "created_at_utc": datetime.now(timezone.utc).isoformat(),
            "validation_plan": plan.get("schema"),
            "staging_dir": plan.get("staging_dir"),
            "notes": "",
        }
        if name == "changed-objects-smoke.json":
            payload["objects"] = [
                {
                    **item,
                    "status": "pending",
                    "notes": "",
                }
                for item in ((plan.get("details") or {}).get("changed_objects") or [])
            ]
        return json.dumps(payload, ensure_ascii=False, indent=2) + "\n"
    if name.endswith(".md"):
        return "\n".join(
            [
                f"# {name}",
                "",
                "Status: pending",
                "",
                "Replace the status line with `Status: passed` only after the disposable-base check is complete.",
                "Record what was checked in the disposable 1C base.",
                "Do not include passwords, tokens, production connection strings, or personal data.",
                "",
            ]
        )
    return "\n".join(
        [
            f"{name}",
            f"Created UTC: {datetime.now(timezone.utc).isoformat()}",
            "Status: pending",
            "",
            "Replace the status line with `Status: passed` only after the disposable-base check is complete.",
            "Paste disposable 1C validation log here.",
            "Do not include passwords, tokens, production connection strings, or personal data.",
            "",
        ]
    )


def create_evidence(plan_path: Path, output_root: Path | None, *, force: bool) -> dict[str, Any]:
    plan = load_json(plan_path)
    if plan.get("schema") != "onec_extension_validation_plan.v1":
        raise SystemExit(f"Unsupported validation plan schema: {plan.get('schema')}")
    if plan.get("status") != "ready_for_disposable_validation":
        raise SystemExit(f"Validation plan is not ready for disposable validation: {plan.get('status')}")

    root = evidence_root(plan, output_root)
    root.mkdir(parents=True, exist_ok=True)
    files = []
    for name in (plan.get("evidence") or {}).get("required_files") or []:
        relative = Path(str(name).replace("\\", "/"))
        if relative.is_absolute() or ".." in relative.parts or not str(relative):
            raise SystemExit(f"Unsafe evidence file name: {name}")
        path = root / relative
        existed = path.exists()
        if existed and not force:
            files.append({"path": str(path), "created": False, "skipped_existing": True})
            continue
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(file_template(str(name), plan), encoding="utf-8")
        files.append({"path": str(path), "created": True, "skipped_existing": False})

    manifest = {
        "schema": "onec_extension_validation_evidence_manifest.v1",
        "created_at_utc": datetime.now(timezone.utc).isoformat(),
        "status": "pending_manual_validation",
        "plan_path": str(plan_path),
        "plan_status": plan.get("status"),
        "staging_dir": plan.get("staging_dir"),
        "evidence_root": str(root),
        "files": files,
        "counts": {
            "files": len(files),
            "created": sum(1 for item in files if item.get("created")),
            "skipped_existing": sum(1 for item in files if item.get("skipped_existing")),
        },
    }
    write_json(root / "_codex_validation_evidence_manifest.json", manifest)
    (root / "README.md").write_text(render_readme(manifest, plan), encoding="utf-8")
    return manifest


def render_readme(manifest: dict[str, Any], plan: dict[str, Any]) -> str:
    lines = [
        "# 1C Extension Validation Evidence",
        "",
        f"Status: `{manifest.get('status')}`",
        f"Validation plan: `{manifest.get('plan_path')}`",
        f"Staging: `{manifest.get('staging_dir')}`",
        "",
        "## Rules",
        "",
        "- Fill these files only with evidence from a disposable 1C base.",
        "- Do not include passwords, tokens, production connection strings, or personal data.",
        "- This folder does not prove validation passed until the evidence checker passes.",
        "",
        "## Required Checks",
        "",
    ]
    for check in plan.get("checks") or []:
        files = ", ".join(f"`{name}`" for name in check.get("expected_evidence") or [])
        lines.append(f"- `{check.get('id')}`: {files}")
    return "\n".join(lines) + "\n"


def main() -> int:
    parser = argparse.ArgumentParser(description="Create manual evidence templates for a 1C extension validation plan.")
    parser.add_argument("--plan", type=Path, required=True)
    parser.add_argument("--output-root", type=Path)
    parser.add_argument("--force", action="store_true")
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    result = create_evidence(args.plan, args.output_root, force=args.force)
    if args.output:
        write_json(args.output, result)
    print(json.dumps({"output": str(args.output) if args.output else None, "status": result["status"], "counts": result["counts"]}, ensure_ascii=False))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
