"""
Comprehensive CLI tests to maximize coverage.

Tests all CLI commands including error handling and edge cases.
"""

import tempfile
from pathlib import Path

import pytest
from typer.testing import CliRunner

from epi_cli.main import app
from epi_core.schemas import ManifestModel
from epi_core.container import EPIContainer


runner = CliRunner()


class TestKeysCommandVariations:
    """Test all keys command variations."""
    
    def test_keys_generate_with_overwrite(self):
        """Test keys generate with overwrite flag."""
        import uuid
        name = f"test_{uuid.uuid4().hex[:8]}"
        
        # Generate first time
        result1 = runner.invoke(app, ["keys", "generate", "--name", name])
        assert result1.exit_code == 0
        
        # Generate again with overwrite
        result2 = runner.invoke(app, ["keys", "generate", "--name", name, "--overwrite"])
        assert result2.exit_code == 0
    
    def test_keys_unknown_action(self):
        """Test keys with unknown action."""
        result = runner.invoke(app, ["keys", "unknown_action"])
        
        assert result.exit_code != 0
        assert "Unknown action" in result.stdout or "unknown" in result.stdout.lower()


class TestVerifyCommandVariations:
    """Test verify command variations."""
    
    @pytest.fixture
    def signed_epi_file(self):
        """Create a signed .epi file."""
        with tempfile.TemporaryDirectory() as tmpdir:
            tmpdir_path = Path(tmpdir)
            source_dir = tmpdir_path / "source"
            source_dir.mkdir()
            (source_dir / "test.txt").write_text("Hello")
            
            output_path = tmpdir_path / "test.epi"
            manifest = ManifestModel(cli_command="test", signature="ed25519:default:fakesig")
            EPIContainer.pack(source_dir, manifest, output_path)
            
            yield output_path
    
    def test_verify_with_signature_but_no_key(self, signed_epi_file):
        """Test verify with signature but missing public key."""
        result = runner.invoke(app, ["verify", "--verbose", str(signed_epi_file)])
        
        # Should handle missing key gracefully or fail due to invalid signature
        assert result.exit_code in [0, 1, 2]

    def test_verify_prints_share_hint_on_success(self):
        """Successful verify output should point to browser verify and team review."""
        with tempfile.TemporaryDirectory() as tmpdir:
            tmpdir_path = Path(tmpdir)
            source_dir = tmpdir_path / "source"
            source_dir.mkdir()
            (source_dir / "test.txt").write_text("Hello")

            output_path = tmpdir_path / "unsigned.epi"
            manifest = ManifestModel(cli_command="test")
            EPIContainer.pack(source_dir, manifest, output_path)

            result = runner.invoke(app, ["verify", str(output_path)])

            assert result.exit_code == 0, result.output
            assert "https://epilabs.org/verify" in result.stdout
            assert "epi connect open" in result.stdout
    
    def test_verify_keyboard_interrupt_handling(self):
        """Test verify handles interrupts gracefully."""
        # This is hard to test directly, but we can verify the code path exists
        from epi_cli.verify import verify_command
        assert callable(verify_command)


class TestViewCommandVariations:
    """Test view command variations."""
    
    def test_view_with_valid_file(self, monkeypatch):
        """Test view with valid .epi file."""
        opened_urls = []
        
        def mock_open(url):
            opened_urls.append(url)
            return True
        
        import epi_cli.view
        monkeypatch.setattr(epi_cli.view, "_open_in_browser", mock_open)
        
        with tempfile.TemporaryDirectory() as tmpdir:
            tmpdir_path = Path(tmpdir)
            source_dir = tmpdir_path / "source"
            source_dir.mkdir()
            (source_dir / "test.txt").write_text("test")
            
            output_path = tmpdir_path / "test.epi"
            manifest = ManifestModel(cli_command="test")
            EPIContainer.pack(source_dir, manifest, output_path)
            
            result = runner.invoke(app, ["view", str(output_path)])

            assert result.exit_code == 0
            assert len(opened_urls) > 0
            assert "https://epilabs.org/verify" in result.stdout
            assert "epi connect open" in result.stdout


class TestCLIHelpMessages:
    """Test CLI help messages and documentation."""
    
    def test_main_help(self):
        """Test main help message."""
        result = runner.invoke(app, ["--help"])
        
        assert result.exit_code == 0
        assert "EPI" in result.stdout or "epi" in result.stdout.lower()
    
    def test_keys_in_help(self):
        """Test that keys command appears in help."""
        result = runner.invoke(app, ["--help"])
        
        assert "keys" in result.stdout.lower()
    
    def test_verify_in_help(self):
        """Test that verify command appears in help."""
        result = runner.invoke(app, ["--help"])
        
        assert "verify" in result.stdout.lower()
    
    def test_view_in_help(self):
        """Test that view command appears in help."""
        result = runner.invoke(app, ["--help"])

        assert "view" in result.stdout.lower()

    def test_connect_open_is_surfaced_in_help(self):
        """Top-level help should surface the local team review path."""
        result = runner.invoke(app, ["--help"])

        assert result.exit_code == 0
        assert "connect open" in result.stdout.lower()

    def test_custom_help_mentions_connect_open(self):
        """epi help should mention the local team review path."""
        result = runner.invoke(app, ["help"])

        assert result.exit_code == 0
        assert "epi connect open" in result.stdout.lower()


class TestVersionCommand:
    """Test version command thoroughly."""
    
    def test_version_shows_version_info(self):
        """Test version command shows version."""
        result = runner.invoke(app, ["version"])
        
        assert result.exit_code == 0
        # Should show version and tagline
        assert "version" in result.stdout.lower() or "epi" in result.stdout.lower()


class TestRecordCommandStub:
    """Test record command registration."""
    
    def test_record_command_registered(self):
        """Test that record command is registered."""
        result = runner.invoke(app, ["--help"])
        
        # Record should be in help
        assert "record" in result.stdout.lower()


class TestCLIMainCallback:
    """Test main CLI callback."""
    
    def test_callback_runs_before_commands(self):
        """Test that callback runs and generates default key."""
        # The callback auto-generates default keypair
        # This is tested implicitly when running any command
        result = runner.invoke(app, ["version"])
        
        assert result.exit_code == 0


class TestKeysHelperFunctions:
    """Test keys helper functions."""
    
    def test_generate_default_keypair_if_missing(self):
        """Test auto-generation of default keypair."""
        from epi_cli.keys import generate_default_keypair_if_missing, KeyManager
        
        with tempfile.TemporaryDirectory() as tmpdir:
            keys_dir = Path(tmpdir) / "keys"
            km = KeyManager(keys_dir=keys_dir)
            
            # Should create default key
            # (we can't easily test the actual function due to console output)
            assert km.keys_dir.exists()
    
    def test_print_keys_table(self):
        """Test keys table printing."""
        from epi_cli.keys import print_keys_table
        
        keys_list = [
            {
                "name": "test",
                "has_private": True,
                "has_public": True,
                "public_path": "/path/to/test.pub",
                "private_path": "/path/to/test.key"
            }
        ]
        
        # Should not crash
        print_keys_table(keys_list)


class TestVerifyReportFormatting:
    """Test verify report formatting functions."""
    
    def test_print_trust_report_high_trust(self):
        """Test trust report with high trust level."""
        from epi_cli.verify import print_trust_report
        
        report = {
            "trust_level": "HIGH",
            "trust_message": "All good",
            "integrity_ok": True,
            "signature_valid": True,
            "signer": "default",
            "files_checked": 5,
            "mismatches_count": 0,
            "workflow_id": "test-id",
            "created_at": "2025-01-01T00:00:00",
            "spec_version": "1.0"
        }
        
        with tempfile.TemporaryDirectory() as tmpdir:
            epi_file = Path(tmpdir) / "test.epi"
            
            # Should not crash
            print_trust_report(report, epi_file, verbose=False)
    
    def test_print_trust_report_medium_trust(self):
        """Test trust report with medium trust level."""
        from epi_cli.verify import print_trust_report
        
        report = {
            "trust_level": "MEDIUM",
            "trust_message": "Unsigned",
            "integrity_ok": True,
            "signature_valid": None,
            "signer": None,
            "files_checked": 3,
            "mismatches_count": 0,
            "workflow_id": "test-id",
            "created_at": "2025-01-01T00:00:00",
            "spec_version": "1.0"
        }
        
        with tempfile.TemporaryDirectory() as tmpdir:
            epi_file = Path(tmpdir) / "test.epi"
            
            print_trust_report(report, epi_file, verbose=True)
    
    def test_print_trust_report_no_trust(self):
        """Test trust report with no trust level."""
        from epi_cli.verify import print_trust_report
        
        report = {
            "trust_level": "NONE",
            "trust_message": "Invalid",
            "integrity_ok": False,
            "signature_valid": False,
            "signer": "fake",
            "files_checked": 2,
            "mismatches_count": 1,
            "mismatches": {"file.txt": "Hash mismatch"},
            "workflow_id": "test-id",
            "created_at": "2025-01-01T00:00:00",
            "spec_version": "1.0"
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            epi_file = Path(tmpdir) / "test.epi"

            print_trust_report(report, epi_file, verbose=True)
