from __future__ import annotations

import contextlib
import io
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from src.cli import main


SECRET_TOKEN = "supersecret-token"
GBP_TOKEN = "gbp-secret-token"
LOCATION_MAP = '{"amsterdam":"LOC1"}'


class TestCliConfig(unittest.TestCase):
    def test_help_lists_expected_subcommands(self) -> None:
        stdout = io.StringIO()
        with contextlib.redirect_stdout(stdout), self.assertRaises(SystemExit) as ctx:
            main(["--help"])

        self.assertEqual(ctx.exception.code, 0)
        text = stdout.getvalue()
        for cmd in ("ingest", "exif", "match", "export", "report", "gbp", "config"):
            self.assertIn(cmd, text)

    def test_config_show_masks_secrets(self) -> None:
        env = {
            "PIPE_DRIVE_API_TOKEN": SECRET_TOKEN,
            "GBP_ACCESS_TOKEN": GBP_TOKEN,
            "GBP_LOCATION_ID_MAP": LOCATION_MAP,
            "OUTPUT_ROOT": "C:\\out",
        }
        stdout = io.StringIO()
        with patch.dict(os.environ, env, clear=True), contextlib.redirect_stdout(stdout):
            code = main(["config", "show"])

        self.assertEqual(code, 0)
        text = stdout.getvalue()
        self.assertNotIn(SECRET_TOKEN, text)
        self.assertNotIn(GBP_TOKEN, text)
        self.assertNotIn(LOCATION_MAP, text)
        self.assertIn("PIPEDRIVE_API_TOKEN: SET", text)
        self.assertIn("GBP_ACCESS_TOKEN: SET", text)
        self.assertIn("GBP_LOCATION_ID_MAP: SET", text)

    def test_config_file_sets_defaults_without_overriding_env(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            config_path = Path(tmp) / "config.env"
            config_path.write_text("INBOX_PATH=C:\\inbox\nOUTPUT_ROOT=C:\\out_from_file\n", encoding="utf-8")

            stdout = io.StringIO()
            with (
                patch.dict(os.environ, {"OUTPUT_ROOT": "C:\\env_out"}, clear=True),
                contextlib.redirect_stdout(stdout),
            ):
                code = main(["--config", str(config_path), "config", "show"])

        self.assertEqual(code, 0)
        text = stdout.getvalue()
        self.assertIn(str(config_path), text)
        self.assertIn("INBOX_PATH: C:\\inbox", text)
        self.assertIn("OUTPUT_ROOT: C:\\env_out", text)
