"""
CLI Integration Tests for Issue #6: Generate Markdown Stub from Schema.

Tests the CLI commands for stub generation functionality.
"""

import json
import pytest
from pathlib import Path
from tempfile import NamedTemporaryFile, TemporaryDirectory
from click.testing import CliRunner

from markitect.cli import cli


class TestIssue6CLIIntegration:
    """Test CLI integration for stub generation."""

    @pytest.fixture
    def runner(self):
        """Create CLI test runner."""
        return CliRunner()

    @pytest.fixture
    def sample_schema_file(self):
        """Create a temporary schema file for testing."""
        schema = {
            "$schema": "http://json-schema.org/draft-07/schema#",
            "type": "object",
            "title": "Test Schema",
            "properties": {
                "headings": {
                    "type": "object",
                    "properties": {
                        "level_1": {
                            "type": "array",
                            "minItems": 1,
                            "maxItems": 1
                        },
                        "level_2": {
                            "type": "array",
                            "minItems": 2,
                            "maxItems": 2
                        }
                    }
                }
            }
        }

        with NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
            json.dump(schema, temp_file)
            temp_file.flush()
            yield Path(temp_file.name)
            Path(temp_file.name).unlink()

    def test_generate_stub_command_exists(self, runner):
        """The generate-stub command should exist in CLI."""
        result = runner.invoke(cli, ['--help'])
        assert result.exit_code == 0
        assert 'generate-stub' in result.output or 'stub-generate' in result.output

    def test_generate_stub_requires_schema_argument(self, runner):
        """generate-stub command should require schema file argument."""
        result = runner.invoke(cli, ['generate-stub'])
        assert result.exit_code != 0
        # Should indicate missing argument

    def test_generate_stub_outputs_to_stdout(self, runner, sample_schema_file):
        """generate-stub should output markdown to stdout by default."""
        result = runner.invoke(cli, ['generate-stub', str(sample_schema_file)])

        assert result.exit_code == 0
        assert result.output is not None
        assert len(result.output.strip()) > 0

        # Should contain markdown heading syntax
        assert '# ' in result.output
        # Should contain some placeholder content
        assert any(keyword in result.output.lower() for keyword in ['todo', 'placeholder', 'content'])

    def test_generate_stub_with_output_file(self, runner, sample_schema_file):
        """generate-stub should save to file when --output specified."""
        with TemporaryDirectory() as temp_dir:
            output_file = Path(temp_dir) / "output.md"

            result = runner.invoke(cli, [
                'generate-stub', str(sample_schema_file),
                '--output', str(output_file)
            ])

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

            content = output_file.read_text()
            assert '# ' in content
            assert len(content.strip()) > 0

    def test_generate_stub_with_different_formats(self, runner, sample_schema_file):
        """generate-stub should support different placeholder styles."""
        # Test default style
        result = runner.invoke(cli, ['generate-stub', str(sample_schema_file)])
        assert result.exit_code == 0
        default_output = result.output

        # Test custom style (if supported)
        result = runner.invoke(cli, [
            'generate-stub', str(sample_schema_file),
            '--style', 'detailed'
        ])
        # Should not fail regardless of whether style is implemented
        assert result.exit_code == 0

    def test_generate_stub_handles_nonexistent_file(self, runner):
        """generate-stub should handle nonexistent schema files gracefully."""
        result = runner.invoke(cli, ['generate-stub', 'nonexistent.json'])
        assert result.exit_code != 0
        assert 'not found' in result.output.lower() or 'error' in result.output.lower()

    def test_generate_stub_handles_invalid_json(self, runner):
        """generate-stub should handle invalid JSON files gracefully."""
        with NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
            temp_file.write("invalid json content")
            temp_file.flush()

            try:
                result = runner.invoke(cli, ['generate-stub', temp_file.name])
                assert result.exit_code != 0
                assert 'error' in result.output.lower() or 'invalid' in result.output.lower()
            finally:
                Path(temp_file.name).unlink()

    def test_generate_stub_verbose_mode(self, runner, sample_schema_file):
        """generate-stub should provide verbose output when requested."""
        result = runner.invoke(cli, [
            '--verbose', 'generate-stub', str(sample_schema_file)
        ])

        assert result.exit_code == 0
        # In verbose mode, should show some processing information on stderr
        # while main output goes to stdout

    def test_generate_stub_with_custom_title(self, runner, sample_schema_file):
        """generate-stub should support custom document titles."""
        result = runner.invoke(cli, [
            'generate-stub', str(sample_schema_file),
            '--title', 'My Custom Document'
        ])

        assert result.exit_code == 0
        assert 'My Custom Document' in result.output

    def test_generate_stub_help_message(self, runner):
        """generate-stub should provide helpful usage information."""
        result = runner.invoke(cli, ['generate-stub', '--help'])
        assert result.exit_code == 0
        assert 'schema' in result.output.lower()
        assert 'generate' in result.output.lower()
        assert 'stub' in result.output.lower() or 'template' in result.output.lower()

    def test_integration_with_schema_generation(self, runner):
        """Should integrate with existing schema generation workflow."""
        # Use the sample blog file we created
        sample_file = Path("sample_blog.md")
        if sample_file.exists():
            with TemporaryDirectory() as temp_dir:
                schema_file = Path(temp_dir) / "generated_schema.json"
                stub_file = Path(temp_dir) / "generated_stub.md"

                # First generate a schema
                result1 = runner.invoke(cli, [
                    'schema-generate', str(sample_file),
                    '--output', str(schema_file)
                ])
                assert result1.exit_code == 0
                assert schema_file.exists()

                # Then generate a stub from that schema
                result2 = runner.invoke(cli, [
                    'generate-stub', str(schema_file),
                    '--output', str(stub_file)
                ])
                assert result2.exit_code == 0
                assert stub_file.exists()

                # Stub should have meaningful content
                stub_content = stub_file.read_text()
                assert '# ' in stub_content
                assert len(stub_content.strip()) > 10