"""Tests for improved hook failure messages in tdd_enforcer and file_checker."""

from __future__ import annotations

import json
import sys
from io import StringIO
from pathlib import Path
from unittest.mock import patch


class TestTddEnforcerMessages:
    def test_warn_outputs_box_drawing(self, tmp_path: Path, capsys):
        sys.path.insert(0, str(Path(__file__).parents[4] / "tribunal" / "hooks"))
        from tribunal.hooks.tdd_enforcer import warn

        result = warn(
            message="No test file found",
            suggestion="Create test_foo.py first",
            file_path=str(tmp_path / "foo.py"),
        )
        captured = capsys.readouterr()
        assert "┌" in captured.err
        assert "└" in captured.err
        assert result == 2

    def test_warn_includes_file_name(self, tmp_path: Path, capsys):
        from tribunal.hooks.tdd_enforcer import warn

        warn(
            message="No test file",
            suggestion="Create test_bar.py",
            file_path="/project/src/bar.py",
        )
        captured = capsys.readouterr()
        assert "bar.py" in captured.err

    def test_warn_includes_fix_suggestion(self, tmp_path, capsys):
        from tribunal.hooks.tdd_enforcer import warn

        warn(
            message="No test",
            suggestion="Create test_baz.py first",
            file_path="/project/baz.py",
        )
        captured = capsys.readouterr()
        assert "test_baz" in captured.err

    def test_block_outputs_box_drawing(self, capsys):
        from tribunal.hooks.tdd_enforcer import block

        result = block(
            message="No failing test for 'auth' module",
            suggestion="Write test_auth.py first",
            file_path="/project/auth.py",
        )
        captured = capsys.readouterr()
        assert "┌" in captured.err
        assert "└" in captured.err
        assert result == 1

    def test_block_includes_affected_tests(self, capsys):
        from tribunal.hooks.tdd_enforcer import block

        block(
            message="No failing test",
            suggestion="Write failing test first",
            affected_tests=["test_user.py", "test_admin.py"],
            file_path="/project/user.py",
        )
        captured = capsys.readouterr()
        assert "test_user" in captured.err or "Affected" in captured.err

    def test_fmt_box_structure(self):
        from tribunal.hooks.tdd_enforcer import _fmt_box

        result = _fmt_box(
            title="Test Title",
            file_path="/project/src/foo.py",
            issue="Some issue",
            details="Some details",
            fix="Do the fix",
        )
        lines = result.splitlines()
        # max 8 lines
        assert len(lines) <= 8
        assert lines[0].startswith("┌")
        assert lines[-1].startswith("└")
        assert "foo.py" in result
        assert "Some issue" in result
        assert "Do the fix" in result


class TestFileCheckerMessages:
    def test_fmt_block_reason_structure(self):
        from tribunal.hooks.file_checker import _fmt_block_reason

        result = _fmt_block_reason(
            file_path="/project/src/config.py",
            issue="Hardcoded secret detected",
            details="AWS_SECRET_KEY found",
            fix="Use env var or secrets manager",
        )
        lines = result.splitlines()
        assert len(lines) <= 8
        assert lines[0].startswith("┌")
        assert lines[-1].startswith("└")
        assert "config.py" in result
        assert "Hardcoded secret" in result
        assert "env var" in result

    def test_secret_block_uses_structured_format(self, tmp_path: Path, capsys):
        from tribunal.hooks.file_checker import main

        py_file = tmp_path / "config.py"
        py_file.write_text("AWS_KEY = 'AKIAIOSFODNN7EXAMPLE'\n")

        with patch("tribunal.hooks.file_checker.get_edited_file_from_stdin", return_value=py_file):
            with patch("tribunal.hooks.file_checker.find_git_root", return_value=tmp_path):
                with patch("tribunal.hooks.file_checker.check_secrets", return_value=(1, "AKIA found")):
                    output = StringIO()
                    with patch("sys.stdout", output):
                        main()
        
        printed = output.getvalue()
        data = json.loads(printed)
        assert data["decision"] == "block"
        assert "┌" in data["reason"]
        assert "Hardcoded secret" in data["reason"]

    def test_language_check_block_uses_structured_format(self, tmp_path: Path):
        from tribunal.hooks.file_checker import main

        py_file = tmp_path / "foo.py"
        py_file.write_text("import os\n")

        with patch("tribunal.hooks.file_checker.get_edited_file_from_stdin", return_value=py_file):
            with patch("tribunal.hooks.file_checker.find_git_root", return_value=tmp_path):
                with patch("tribunal.hooks.file_checker.check_secrets", return_value=(0, "")):
                    with patch("tribunal.hooks.file_checker.check_python", return_value=(1, "Syntax error on line 5")):
                        output = StringIO()
                        with patch("sys.stdout", output):
                            main()

        data = json.loads(output.getvalue())
        assert data["decision"] == "block"
        assert "┌" in data["reason"]
        assert "py check failed" in data["reason"]

    def test_allowed_file_outputs_empty_json(self, tmp_path: Path):
        from tribunal.hooks.file_checker import main

        py_file = tmp_path / "clean.py"
        py_file.write_text("x = 1\n")

        with patch("tribunal.hooks.file_checker.get_edited_file_from_stdin", return_value=py_file):
            with patch("tribunal.hooks.file_checker.find_git_root", return_value=tmp_path):
                with patch("tribunal.hooks.file_checker.check_secrets", return_value=(0, "")):
                    with patch("tribunal.hooks.file_checker.check_python", return_value=(0, "")):
                        output = StringIO()
                        with patch("sys.stdout", output):
                            result = main()

        assert result == 0
        data = json.loads(output.getvalue())
        assert data == {}
