from __future__ import annotations

import io
import os
import unittest
from contextlib import redirect_stderr, redirect_stdout
from pathlib import Path
from tempfile import TemporaryDirectory

from doc2md.cli import main


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


class CliContractTest(unittest.TestCase):
    def setUp(self) -> None:
        self._history_env = os.environ.get("DOC2MD_HISTORY_DB")
        os.environ["DOC2MD_HISTORY_DB"] = "disable"

    def tearDown(self) -> None:
        if self._history_env is None:
            os.environ.pop("DOC2MD_HISTORY_DB", None)
        else:
            os.environ["DOC2MD_HISTORY_DB"] = self._history_env

    def _run(self, argv: list[str]) -> tuple[int, str, str]:
        stdout = io.StringIO()
        stderr = io.StringIO()
        with redirect_stdout(stdout), redirect_stderr(stderr):
            code = main(argv)
        return code, stdout.getvalue(), stderr.getvalue()

    def test_stdout_output_for_dash(self) -> None:
        input_path = FIX_IN / "sample.csv"
        expected = (FIX_OUT / "sample.csv.md").read_text(encoding="utf-8")
        code, out, err = self._run(
            [str(input_path), "--format", "csv", "-o", "-", "--quiet"]
        )
        self.assertEqual(code, 0)
        self.assertEqual(out, expected)
        self.assertEqual(err, "")

    def test_file_output_suppresses_stdout(self) -> None:
        input_path = FIX_IN / "sample.csv"
        expected = (FIX_OUT / "sample.csv.md").read_text(encoding="utf-8")
        with TemporaryDirectory() as temp_dir:
            output_path = Path(temp_dir) / "out.md"
            code, out, err = self._run(
                [
                    str(input_path),
                    "--format",
                    "csv",
                    "-o",
                    str(output_path),
                    "--quiet",
                ]
            )
            self.assertEqual(code, 0)
            self.assertEqual(out, "")
            self.assertEqual(err, "")
            self.assertTrue(output_path.exists())
            self.assertEqual(output_path.read_text(encoding="utf-8"), expected)

    def test_unsupported_extension_exit_code(self) -> None:
        with TemporaryDirectory() as temp_dir:
            input_path = Path(temp_dir) / "sample.txt"
            input_path.write_text("hello", encoding="utf-8")
            code, out, err = self._run([str(input_path), "--quiet"])
            self.assertEqual(code, 3)
            self.assertEqual(out, "")
            self.assertIn("Unsupported extension", err)
