"""
CLI Integration Tests - Prevent CLI Entry Point Regressions

This test module validates that the CLI entry point is properly accessible
and core commands work as expected. It prevents regressions like broken
imports or missing entry points that would break user accessibility.

Tests focus on:
- CLI entry point accessibility (markitect --help)
- Core command availability and help text
- Template rendering CLI functionality
- Error handling in CLI commands
"""

import subprocess
import tempfile
import json
import os
import pytest
from pathlib import Path


class TestCLIEntryPoint:
    """Test CLI entry point accessibility."""

    def test_markitect_help_accessible(self):
        """Test that markitect --help works and shows expected content.

        This prevents regressions where import errors break CLI accessibility.
        """
        # Run markitect --help
        result = subprocess.run(
            ['markitect', '--help'],
            capture_output=True,
            text=True
        )

        # Should exit successfully
        assert result.returncode == 0, f"CLI help failed with error: {result.stderr}"

        # Should contain core CLI information
        output = result.stdout
        assert "MarkiTect - Advanced Markdown engine" in output
        assert "Commands:" in output
        assert "--help" in output

        # Should not have import errors
        assert "ModuleNotFoundError" not in result.stderr
        assert "ImportError" not in result.stderr

    def test_core_commands_available(self):
        """Test that core commands are listed in help output."""
        result = subprocess.run(
            ['markitect', '--help'],
            capture_output=True,
            text=True
        )

        output = result.stdout

        # Core functionality commands
        assert "ingest" in output
        assert "list" in output
        assert "status" in output or "stats" in output

        # Template engine command (Issue #65)
        assert "template-render" in output

        # Schema commands
        assert "schema-generate" in output
        assert "validate" in output

    def test_template_render_command_help(self):
        """Test that template-render command help is accessible."""
        result = subprocess.run(
            ['markitect', 'template-render', '--help'],
            capture_output=True,
            text=True
        )

        assert result.returncode == 0
        output = result.stdout

        assert "Render a template with data" in output
        assert "TEMPLATE_FILE" in output
        assert "DATA_FILE" in output
        assert "--output" in output
        assert "--strict" in output
        assert "--lenient" in output


class TestTemplateRenderCLI:
    """Test template-render CLI functionality end-to-end."""

    def test_template_render_basic_functionality(self):
        """Test basic template rendering via CLI."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create test template
            template_file = temp_path / "test.md"
            template_file.write_text("# {{title}}\n\nHello {{name}}!")

            # Create test data
            data_file = temp_path / "data.json"
            data = {"title": "Test Document", "name": "World"}
            data_file.write_text(json.dumps(data))

            # Run template rendering
            result = subprocess.run(
                ['markitect', 'template-render', str(template_file), str(data_file)],
                capture_output=True,
                text=True
            )

            assert result.returncode == 0, f"Template rendering failed: {result.stderr}"

            output = result.stdout
            assert "# Test Document" in output
            assert "Hello World!" in output

    def test_template_render_with_output_file(self):
        """Test template rendering with output file option."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create test files
            template_file = temp_path / "template.md"
            template_file.write_text("Result: {{value}}")

            data_file = temp_path / "data.json"
            data_file.write_text(json.dumps({"value": "SUCCESS"}))

            output_file = temp_path / "output.md"

            # Run with output option
            result = subprocess.run(
                ['markitect', 'template-render',
                 str(template_file), str(data_file),
                 '--output', str(output_file)],
                capture_output=True,
                text=True
            )

            assert result.returncode == 0
            assert "Template rendered successfully" in result.stdout

            # Check output file was created
            assert output_file.exists()
            content = output_file.read_text()
            assert "Result: SUCCESS" in content

    def test_template_render_validation_mode(self):
        """Test template rendering with validation options."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create valid template
            template_file = temp_path / "valid.md"
            template_file.write_text("Valid: {{name}}")

            data_file = temp_path / "data.json"
            data_file.write_text(json.dumps({"name": "test"}))

            # Run with validation
            result = subprocess.run(
                ['markitect', 'template-render',
                 str(template_file), str(data_file),
                 '--validate', '--check-data'],
                capture_output=True,
                text=True
            )

            assert result.returncode == 0
            assert "Valid: test" in result.stdout

    def test_template_render_error_handling(self):
        """Test CLI error handling for invalid inputs."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Test with non-existent template file
            result = subprocess.run(
                ['markitect', 'template-render', 'nonexistent.md', 'data.json'],
                capture_output=True,
                text=True
            )

            assert result.returncode != 0
            assert "does not exist" in result.stderr.lower() or "not found" in result.stderr.lower()

    def test_template_render_strict_vs_lenient_mode(self):
        """Test strict vs lenient mode behavior."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Template with missing variable
            template_file = temp_path / "template.md"
            template_file.write_text("Hello {{name}}, missing: {{missing}}")

            # Data missing the 'missing' variable
            data_file = temp_path / "data.json"
            data_file.write_text(json.dumps({"name": "Alice"}))

            # Test strict mode (should fail)
            result_strict = subprocess.run(
                ['markitect', 'template-render', str(template_file), str(data_file), '--strict'],
                capture_output=True,
                text=True
            )

            assert result_strict.returncode != 0

            # Test lenient mode (should succeed)
            result_lenient = subprocess.run(
                ['markitect', 'template-render', str(template_file), str(data_file), '--lenient'],
                capture_output=True,
                text=True
            )

            assert result_lenient.returncode == 0
            output = result_lenient.stdout
            assert "Hello Alice" in output
            assert "{{missing}}" in output  # Placeholder preserved


class TestCLIRegressionPrevention:
    """Tests specifically designed to catch common CLI regression patterns."""

    def test_import_paths_valid(self):
        """Test that all CLI module imports work correctly.

        This catches issues like the domain module import that broke CLI access.
        """
        # Try to import the CLI module directly
        try:
            import markitect.cli
            # Should not raise ImportError or ModuleNotFoundError
        except (ImportError, ModuleNotFoundError) as e:
            pytest.fail(f"CLI module import failed: {e}")

    def test_cli_entry_point_configuration(self):
        """Test that the CLI entry point is properly configured."""
        # Check that the entry point script exists and is executable
        import shutil
        markitect_path = shutil.which('markitect')

        assert markitect_path is not None, "markitect command not found in PATH"
        assert os.access(markitect_path, os.X_OK), "markitect command is not executable"

    def test_no_runtime_import_errors(self):
        """Test that basic CLI commands don't have runtime import errors."""
        # Test a few key commands to ensure no import errors at runtime
        commands_to_test = [
            ['markitect', '--version'],  # Should show version or error gracefully
            ['markitect', 'list', '--help'],  # Core command help
            ['markitect', 'template-render', '--help'],  # New template command help
        ]

        for cmd in commands_to_test:
            result = subprocess.run(cmd, capture_output=True, text=True)

            # Even if command fails, it shouldn't be due to import errors
            assert "ModuleNotFoundError" not in result.stderr
            assert "ImportError" not in result.stderr
            assert "No module named" not in result.stderr

    def test_template_engine_availability(self):
        """Test that template engine is properly available to CLI."""
        # Create minimal test to ensure template engine can be imported by CLI
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            template_file = temp_path / "minimal.md"
            template_file.write_text("test")

            data_file = temp_path / "minimal.json"
            data_file.write_text("{}")

            # This should not fail with import errors
            result = subprocess.run(
                ['markitect', 'template-render', str(template_file), str(data_file)],
                capture_output=True,
                text=True
            )

            # Should succeed or fail gracefully, but not with import errors
            assert "ImportError" not in result.stderr
            assert "ModuleNotFoundError" not in result.stderr
            assert "Template engine not available" not in result.stderr


if __name__ == '__main__':
    pytest.main([__file__, '-v'])