"""
Tests for Issue #51: Add outline mode to schema generation

This test module implements comprehensive tests for the new outline mode functionality
that captures document structure with actual heading text and depth control.

Following TDD8 methodology - these tests are written before implementation.
"""

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

from markitect.cli import cli
from markitect.schema_generator import SchemaGenerator
from markitect.exceptions import InvalidDepthError


class TestIssue51OutlineMode:
    """Test suite for outline mode schema generation functionality."""

    def setup_method(self):
        """Set up test fixtures."""
        self.schema_generator = SchemaGenerator()
        self.runner = CliRunner()

    def test_cli_accepts_mode_outline_option(self):
        """Test that CLI accepts --mode outline option."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.

### Details
Some details here.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0, f"CLI should accept --mode outline option, got: {result.output}"

        finally:
            temp_file.unlink()

    def test_cli_accepts_depth_parameter(self):
        """Test that CLI accepts --depth parameter with outline mode."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.

### Details
Some details here.

#### Specifics
Very specific information.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                '--depth', '2',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0, f"CLI should accept --depth parameter, got: {result.output}"

        finally:
            temp_file.unlink()

    def test_outline_mode_generates_schema_with_from_title(self):
        """Test that outline mode generates schema with 'from' in title instead of 'for'."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0
            schema = json.loads(result.output)
            expected_title = f"Schema from {temp_file.name}"
            assert schema["title"] == expected_title, f"Expected title 'Schema from {temp_file.name}', got '{schema.get('title')}'"

        finally:
            temp_file.unlink()

    def test_outline_mode_captures_actual_heading_text(self):
        """Test that outline mode captures actual heading text in schema."""
        # Arrange
        markdown_content = """# Main Architecture Document

## System Overview
High-level system description.

### Core Components
Details about main components.

## Implementation Strategy
Strategy for implementation.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0
            schema = json.loads(result.output)

            # Check that headings properties exist and contain actual text
            assert "headings" in schema["properties"], "Schema should contain headings property"

            # Should have level_1, level_2, level_3 based on content
            headings = schema["properties"]["headings"]["properties"]
            assert "level_1" in headings, "Should have level_1 headings"
            assert "level_2" in headings, "Should have level_2 headings"
            assert "level_3" in headings, "Should have level_3 headings"

            # Check heading text is captured (this will need to be implemented)
            # For now, verify structure exists
            level_1_schema = headings["level_1"]
            assert level_1_schema["type"] == "array"
            assert "items" in level_1_schema

        finally:
            temp_file.unlink()

    def test_outline_mode_with_depth_limit_respects_depth(self):
        """Test that outline mode with --depth parameter respects depth limit."""
        # Arrange
        markdown_content = """# Main Document

## Section A
Content A.

### Subsection A1
Content A1.

#### Deep Section A1.1
Very deep content.

## Section B
Content B.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                '--depth', '2',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0
            schema = json.loads(result.output)

            headings = schema["properties"]["headings"]["properties"]
            assert "level_1" in headings, "Should have level_1 headings"
            assert "level_2" in headings, "Should have level_2 headings"
            assert "level_3" not in headings, "Should not have level_3 headings with depth=2"
            assert "level_4" not in headings, "Should not have level_4 headings with depth=2"

        finally:
            temp_file.unlink()

    def test_outline_mode_integrates_with_metaschema_extensions(self):
        """Test that outline mode integrates with metaschema extensions from Issue #50."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                '--depth', '3',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0
            schema = json.loads(result.output)

            # Check for metaschema extensions
            assert "x-markitect-outline-mode" in schema, "Should have outline mode marker"
            assert schema["x-markitect-outline-mode"] is True, "Outline mode should be marked as true"

            assert "x-markitect-outline-depth" in schema, "Should have outline depth marker"
            assert schema["x-markitect-outline-depth"] == 3, "Should record the depth setting"

        finally:
            temp_file.unlink()

    def test_outline_mode_works_with_outfile_parameter(self):
        """Test that outline mode works with existing --outfile parameter."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        with NamedTemporaryFile(mode='w', suffix='.json', delete=False) as outf:
            output_file = Path(outf.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                '--outfile', str(output_file),
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0
            assert output_file.exists(), "Output file should be created"

            schema_content = output_file.read_text()
            schema = json.loads(schema_content)

            expected_title = f"Schema from {temp_file.name}"
            assert schema["title"] == expected_title

        finally:
            temp_file.unlink()
            if output_file.exists():
                output_file.unlink()

    def test_cli_maintains_backward_compatibility_with_max_depth(self):
        """Test that existing --max-depth option still works with default mode."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.

### Details
Some details here.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--max-depth', '2',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code == 0, f"CLI should maintain backward compatibility with --max-depth, got: {result.output}"
            schema = json.loads(result.output)

            # Should use old title format for backward compatibility
            expected_title = f"Schema for {temp_file.name}"
            assert schema["title"] == expected_title, f"Default mode should use 'for' in title"

        finally:
            temp_file.unlink()

    def test_depth_parameter_validation(self):
        """Test that --depth parameter validates input correctly."""
        # Arrange
        markdown_content = """# Test Document

## Introduction
This is a test document.
"""

        with NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(markdown_content)
            temp_file = Path(f.name)

        try:
            # Act - Test invalid depth
            result = self.runner.invoke(cli, [
                'schema-generate',
                '--mode', 'outline',
                '--depth', '0',
                str(temp_file)
            ])

            # Assert
            assert result.exit_code != 0, "Should reject depth=0"
            assert "Invalid depth parameter" in result.output or "depth must be >= 1" in result.output

        finally:
            temp_file.unlink()

    def test_cli_help_includes_new_options(self):
        """Test that CLI help text includes documentation for new options."""
        # Act
        result = self.runner.invoke(cli, ['schema-generate', '--help'])

        # Assert
        assert result.exit_code == 0
        help_text = result.output
        assert "--mode" in help_text, "Help should document --mode option"
        assert "--depth" in help_text, "Help should document --depth option"
        assert "outline" in help_text, "Help should mention outline mode"