"""
Tests for Issue #132: CLI Integration and Command Interface

This module tests the complete CLI command execution and integration
with the existing markitect command system.
"""

import pytest
import tempfile
import os
from pathlib import Path
from unittest.mock import patch, MagicMock
from click.testing import CliRunner

# Add project root to path for imports
import sys
project_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(project_root))


class TestIssue132CLIIntegration:
    """Test complete CLI command execution and integration."""

    def setup_method(self):
        """Set up test environment."""
        self.runner = CliRunner()
        self.temp_dir = tempfile.mkdtemp()

        # Sample markdown content for testing
        self.test_markdown = """# CLI Test Document

This is a test document for CLI integration testing.

## Features
- Command line interface
- File input/output
- Option parsing
- Error handling

### Code Example
```bash
markitect md-render input.md --output result.html
```
"""

    def teardown_method(self):
        """Clean up test environment."""
        import shutil
        shutil.rmtree(self.temp_dir, ignore_errors=True)

    def test_md_render_command_registered_in_cli(self):
        """Test that md-render command is registered in main CLI - Issue #132."""
        from markitect.cli import cli

        # Should find md-render in available commands
        assert 'md-render' in cli.commands

        cmd = cli.commands['md-render']
        assert cmd.name == 'md-render'

    def test_basic_command_execution_with_input_output(self):
        """Test basic md-render command execution with file paths - Issue #132."""
        # Create test input file
        input_file = Path(self.temp_dir) / "input.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "output.html"

        # Test actual command execution
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file)
        ])

        # Should execute successfully
        assert result.exit_code == 0
        assert output_file.exists()

    def test_command_with_template_option(self):
        """Test md-render command with template option - Issue #132."""
        input_file = Path(self.temp_dir) / "template_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "template_output.html"

        # Test template option
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--template', 'github'
        ])

        assert result.exit_code == 0
        assert output_file.exists()

    def test_command_with_css_option(self):
        """Test md-render command with custom CSS option - Issue #132."""
        # Create custom CSS file
        css_content = "body { background: lightblue; }"
        css_file = Path(self.temp_dir) / "custom.css"
        css_file.write_text(css_content)

        input_file = Path(self.temp_dir) / "css_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "css_output.html"

        # Test CSS option functionality
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--css', str(css_file)
        ])

        assert result.exit_code == 0
        assert output_file.exists()

        # Verify CSS was included
        html_content = output_file.read_text()
        assert 'background: lightblue' in html_content

    def test_command_help_text(self):
        """Test that md-render command has proper help text - Issue #132."""
        from markitect.cli import cli

        result = self.runner.invoke(cli, ['md-render', '--help'])

        # Should display help information
        assert result.exit_code == 0
        assert 'markdown' in result.output.lower()
        assert 'html' in result.output.lower()
        assert '--output' in result.output
        assert '--template' in result.output
        assert 'basic' in result.output
        assert 'github' in result.output
        assert 'dark' in result.output

    def test_missing_input_file_error_handling(self):
        """Test error handling when input file doesn't exist - Issue #132."""
        nonexistent_file = Path(self.temp_dir) / "does_not_exist.md"
        output_file = Path(self.temp_dir) / "error_output.html"

        # Test error handling for missing file
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(nonexistent_file),
            '--output', str(output_file)
        ])

        # Should exit with error code (Click handles file validation)
        assert result.exit_code != 0
        assert 'does not exist' in result.output or 'not found' in result.output.lower()

    def test_invalid_template_error_handling(self):
        """Test error handling for invalid template names - Issue #132."""
        input_file = Path(self.temp_dir) / "template_error.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "template_error_output.html"

        # Test invalid template handling
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--template', 'invalid_template_name'
        ])

        # Should exit with error code (Click choice validation)
        assert result.exit_code != 0
        assert 'invalid choice' in result.output.lower() or 'not one of' in result.output.lower()

    def test_output_directory_creation(self):
        """Test that output directory is created if it doesn't exist - Issue #132."""
        input_file = Path(self.temp_dir) / "dir_test.md"
        input_file.write_text(self.test_markdown)

        # Output in non-existent directory
        output_dir = Path(self.temp_dir) / "new_directory"
        output_file = output_dir / "output.html"

        # Test directory creation
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file)
        ])

        assert result.exit_code == 0
        assert output_dir.exists()
        assert output_file.exists()

    def test_verbose_output_option(self):
        """Test basic output without verbose (verbose not implemented yet) - Issue #132."""
        input_file = Path(self.temp_dir) / "verbose_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "verbose_output.html"

        # Test basic command execution (verbose flag not implemented yet)
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file)
        ])

        assert result.exit_code == 0
        assert output_file.exists()
        # Should contain basic success message
        assert 'generated' in result.output.lower() or '✓' in result.output

    def test_dry_run_option(self):
        """Test that dry-run option is not yet implemented - Issue #132."""
        input_file = Path(self.temp_dir) / "dry_run_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "dry_run_output.html"

        # Dry-run option not implemented yet - should give unknown option error
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--dry-run'
        ])

        # Should exit with error code for unknown option
        assert result.exit_code != 0
        assert 'no such option' in result.output.lower() or 'unrecognized' in result.output.lower()

    def test_default_output_filename_generation(self):
        """Test default output filename generation when not specified - Issue #132."""
        input_file = Path(self.temp_dir) / "default_name.md"
        input_file.write_text(self.test_markdown)

        # Default naming IS implemented - should work
        from markitect.cli import cli

        result = self.runner.invoke(cli, ['md-render', str(input_file)])

        assert result.exit_code == 0

        # Should create default_name.html
        expected_output = Path(self.temp_dir) / "default_name.html"
        assert expected_output.exists()

    def test_plugin_integration_with_markdown_commands(self):
        """Test integration with existing MarkdownCommandsPlugin - Issue #132."""
        # Plugin integration IS implemented and working
        from markitect.plugins.builtin.markdown_commands import MarkdownCommandsPlugin

        plugin = MarkdownCommandsPlugin()

        commands = plugin.get_commands()

        # Should include md-render alongside existing commands
        assert 'md-render' in commands
        assert 'md-ingest' in commands
        assert 'md-get' in commands
        assert 'md-list' in commands

    def test_command_follows_existing_cli_patterns(self):
        """Test that md-render follows existing CLI command patterns - Issue #132."""
        # Command structure IS implemented and working
        from markitect.cli import cli

        # Should follow same patterns as other md-* commands
        md_commands = [name for name in cli.commands.keys() if name.startswith('md-')]

        assert 'md-render' in md_commands

        # All md- commands should have consistent help format
        for cmd_name in md_commands:
            cmd = cli.commands[cmd_name]
            assert cmd.help is not None
            assert len(cmd.help) > 0