#!/usr/bin/env python3
"""Run the full read-only preflight for a 1C patch workspace."""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any

from check_1c_patch_source_freshness import check_workspace_sources
from check_1c_patch_workspace_integrity import check_workspace
from diff_1c_patch_workspace import build_diff
from validate_1c_patch_workspace_semantics import validate_workspace


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


def safety_from_workspace(workspace: Path) -> dict[str, Any]:
    path = workspace / "safety.json"
    if not path.exists():
        return {
            "schema": "onec_change_proposal_safety_check.v1",
            "passed": False,
            "findings": [{"severity": "error", "code": "missing_safety_json", "message": f"Missing {path}"}],
            "counts": {"errors": 1, "warnings": 0},
        }
    return load_json(path)


def status_from_checks(safety: dict[str, Any], integrity: dict[str, Any], freshness: dict[str, Any], semantic: dict[str, Any], diff: dict[str, Any]) -> str:
    if not safety.get("passed") or not integrity.get("passed") or not freshness.get("passed") or not semantic.get("passed") or not diff.get("passed"):
        return "blocked"
    modified = (diff.get("counts") or {}).get("modified", 0)
    if modified:
        return "ready_for_review"
    return "ready_for_editing"


def collect_gate(name: str, data: dict[str, Any]) -> dict[str, Any]:
    return {
        "name": name,
        "schema": data.get("schema"),
        "passed": data.get("passed"),
        "counts": data.get("counts"),
    }


def next_actions(status: str) -> list[str]:
    if status == "blocked":
        return [
            "Inspect failed gates and recreate the workspace if source files changed.",
            "Do not generate, package, or apply patches until all gates pass.",
        ]
    if status == "ready_for_editing":
        return [
            "Edit only files under working/.",
            "Run preflight again after edits; BSL/Form.xml semantic validation is included.",
        ]
    return [
        "Review the workspace diff.",
        "Run external BSL/1C validation in a disposable base before packaging or applying.",
    ]


def build_preflight(workspace: Path, *, max_patch_chars: int) -> dict[str, Any]:
    safety = safety_from_workspace(workspace)
    integrity = check_workspace(workspace)
    freshness = check_workspace_sources(workspace)
    semantic = validate_workspace(workspace)
    diff = build_diff(workspace, max_patch_chars=max_patch_chars)
    status = status_from_checks(safety, integrity, freshness, semantic, diff)
    return {
        "schema": "onec_patch_preflight.v1",
        "workspace": str(workspace),
        "status": status,
        "passed": status != "blocked",
        "gates": [
            collect_gate("proposal_safety", safety),
            collect_gate("workspace_integrity", integrity),
            collect_gate("source_freshness", freshness),
            collect_gate("workspace_semantic_validation", semantic),
            collect_gate("workspace_diff", diff),
        ],
        "diff_summary": diff.get("counts"),
        "next_actions": next_actions(status),
        "details": {
            "safety": safety,
            "integrity": integrity,
            "freshness": freshness,
            "semantic": semantic,
            "diff": diff,
        },
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Run 1C patch workspace preflight.")
    parser.add_argument("--workspace", type=Path, required=True)
    parser.add_argument("--max-patch-chars", type=int, default=200000)
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    result = build_preflight(args.workspace, max_patch_chars=args.max_patch_chars)
    output = json.dumps(result, ensure_ascii=False, indent=2) + "\n"
    if args.output:
        args.output.parent.mkdir(parents=True, exist_ok=True)
        args.output.write_text(output, encoding="utf-8")
    print(json.dumps({"output": str(args.output) if args.output else None, "passed": result["passed"], "status": result["status"], "diff": result["diff_summary"]}, ensure_ascii=False))
    return 0 if result["passed"] else 2


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