from __future__ import annotations

import json
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
FIX_IN = ROOT / "tests" / "fixtures" / "in"


def run_cli(args: list[str], env: dict[str, str]) -> subprocess.CompletedProcess[str]:
    return subprocess.run(
        [sys.executable, "-m", "doc2md.cli", *args],
        cwd=ROOT,
        text=True,
        capture_output=True,
        env=env,
    )


class ExplainCommandTest(unittest.TestCase):
    def test_explain_json_payload(self) -> None:
        input_path = FIX_IN / "sample.csv"
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "history.db"
            output_path = Path(tmpdir) / "out.md"
            env = os.environ.copy()
            env["DOC2MD_HISTORY_DB"] = str(db_path)

            convert = run_cli(
                [str(input_path), "-o", str(output_path), "--quiet", "--yes"],
                env,
            )
            self.assertEqual(convert.returncode, 0)

            history = run_cli(["history", "--json"], env)
            self.assertEqual(history.returncode, 0)
            runs = json.loads(history.stdout)
            run_id = runs[0]["id"]

            explain = run_cli(["explain", str(run_id), "--json"], env)
            self.assertEqual(explain.returncode, 0)
            payload = json.loads(explain.stdout)
            self.assertEqual(payload["id"], run_id)
            self.assertEqual(payload["exit_code"], 0)
            self.assertEqual(payload["status"], "success")
            self.assertIn("options", payload)
            self.assertIn("inputs", payload)
            self.assertIn("outputs", payload)
            self.assertIn("timings", payload)
            stages = {item["stage"] for item in payload["timings"]}
            self.assertTrue({"detect", "convert", "write", "total"}.issubset(stages))

    def test_explain_includes_overwrite_warning(self) -> None:
        input_path = FIX_IN / "sample.csv"
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "history.db"
            output_path = Path(tmpdir) / "out.md"
            env = os.environ.copy()
            env["DOC2MD_HISTORY_DB"] = str(db_path)

            first = run_cli(
                [str(input_path), "-o", str(output_path), "--quiet", "--yes"],
                env,
            )
            self.assertEqual(first.returncode, 0)
            second = run_cli(
                [str(input_path), "-o", str(output_path), "--quiet", "--yes"],
                env,
            )
            self.assertEqual(second.returncode, 0)

            history = run_cli(["history", "--json"], env)
            self.assertEqual(history.returncode, 0)
            runs = json.loads(history.stdout)
            run_id = runs[0]["id"]

            explain = run_cli(["explain", str(run_id), "--json"], env)
            self.assertEqual(explain.returncode, 0)
            payload = json.loads(explain.stdout)
            codes = {item["code"] for item in payload["warnings"]}
            self.assertIn("overwrite", codes)


if __name__ == "__main__":
    unittest.main()
