"""
Test directory structure analysis functionality for Issue #139: Implode directory to a markdown file.

This test module covers the analysis of directory structures to identify hierarchical
organization and markdown files for the implosion process.
"""

import pytest
import tempfile
import shutil
from pathlib import Path
from unittest.mock import Mock, patch

# Import will fail initially (RED phase) until implementation exists
try:
    from markitect.plugins.builtin.markdown_commands import (
        analyze_directory_structure,
        scan_markdown_files,
        detect_hierarchy_from_structure,
        DirectoryNode,
        identify_index_files
    )
except ImportError:
    # Expected during RED phase - tests should fail initially
    analyze_directory_structure = None
    scan_markdown_files = None
    detect_hierarchy_from_structure = None
    DirectoryNode = None
    identify_index_files = None


class TestDirectoryStructureAnalysis:
    """Test analysis of directory structures for implosion."""

    def setup_method(self):
        """Set up temporary directory for each test."""
        self.temp_dir = Path(tempfile.mkdtemp())

    def teardown_method(self):
        """Clean up temporary directory after each test."""
        if self.temp_dir.exists():
            shutil.rmtree(self.temp_dir)

    def test_scan_simple_markdown_files(self):
        """Test scanning directory for markdown files."""
        # This should fail initially (RED phase)

        # Create test structure
        (self.temp_dir / "chapter_1.md").write_text("# Chapter 1\nContent here.")
        (self.temp_dir / "chapter_2.md").write_text("# Chapter 2\nMore content.")
        (self.temp_dir / "not_markdown.txt").write_text("Not a markdown file.")

        markdown_files = scan_markdown_files(self.temp_dir)

        # Should find only markdown files
        assert len(markdown_files) == 2
        file_names = [f.name for f in markdown_files]
        assert "chapter_1.md" in file_names
        assert "chapter_2.md" in file_names
        assert "not_markdown.txt" not in file_names

    def test_scan_nested_directory_structure(self):
        """Test scanning nested directories for markdown files."""
        # This should fail initially (RED phase)

        # Create nested structure
        part_dir = self.temp_dir / "part_1_introduction"
        part_dir.mkdir()
        (part_dir / "index.md").write_text("# Part 1: Introduction\nIntro content.")

        chapter_dir = part_dir / "chapter_1_getting_started"
        chapter_dir.mkdir()
        (chapter_dir / "index.md").write_text("## Chapter 1: Getting Started\nChapter content.")
        (chapter_dir / "section_1_1_installation.md").write_text("### Section 1.1: Installation\nInstall info.")

        markdown_files = scan_markdown_files(self.temp_dir, recursive=True)

        # Should find all markdown files in nested structure
        assert len(markdown_files) >= 3
        file_paths = [str(f) for f in markdown_files]
        assert any("part_1_introduction/index.md" in path for path in file_paths)
        assert any("chapter_1_getting_started/index.md" in path for path in file_paths)
        assert any("section_1_1_installation.md" in path for path in file_paths)

    def test_detect_hierarchy_from_directory_depth(self):
        """Test detecting hierarchy levels based on directory depth."""
        # This should fail initially (RED phase)

        # Create structure with different depths
        (self.temp_dir / "root_file.md").write_text("# Root Level")

        level1_dir = self.temp_dir / "level_1"
        level1_dir.mkdir()
        (level1_dir / "file.md").write_text("## Level 1")

        level2_dir = level1_dir / "level_2"
        level2_dir.mkdir()
        (level2_dir / "file.md").write_text("### Level 2")

        hierarchy = detect_hierarchy_from_structure(self.temp_dir)

        # Should detect proper hierarchy levels
        assert hierarchy is not None
        assert len(hierarchy) > 0

        # Root level should be detected
        root_items = [item for item in hierarchy if item.depth == 0]
        assert len(root_items) >= 1

        # Nested levels should be detected
        nested_items = [item for item in hierarchy if item.depth > 0]
        assert len(nested_items) > 0

    def test_identify_index_files_vs_content_files(self):
        """Test identification of index.md files vs regular content files."""
        # This should fail initially (RED phase)

        # Create mixed structure
        section_dir = self.temp_dir / "section_1"
        section_dir.mkdir()
        (section_dir / "index.md").write_text("# Section 1\nSection intro.")
        (section_dir / "subsection_a.md").write_text("## Subsection A\nContent A.")
        (section_dir / "subsection_b.md").write_text("## Subsection B\nContent B.")

        analysis = identify_index_files(section_dir)

        # Should distinguish index files from content files
        assert analysis.index_file is not None
        assert analysis.index_file.name == "index.md"
        assert len(analysis.content_files) == 2

        content_names = [f.name for f in analysis.content_files]
        assert "subsection_a.md" in content_names
        assert "subsection_b.md" in content_names

    def test_analyze_complex_directory_structure(self):
        """Test analysis of a complex directory structure like md-explode output."""
        # This should fail initially (RED phase)

        # Create structure similar to md-explode output
        part1_dir = self.temp_dir / "part_1_introduction"
        part1_dir.mkdir()
        (part1_dir / "index.md").write_text("# Part 1: Introduction\nPart content.")

        chapter1_dir = part1_dir / "chapter_1_getting_started"
        chapter1_dir.mkdir()
        (chapter1_dir / "index.md").write_text("## Chapter 1: Getting Started\nChapter content.")
        (chapter1_dir / "section_1_1_setup.md").write_text("### Section 1.1: Setup\nSetup content.")
        (chapter1_dir / "section_1_2_config.md").write_text("### Section 1.2: Config\nConfig content.")

        part2_dir = self.temp_dir / "part_2_advanced"
        part2_dir.mkdir()
        (part2_dir / "chapter_2_1_algorithms.md").write_text("## Chapter 2.1: Algorithms\nAlgo content.")

        structure = analyze_directory_structure(self.temp_dir)

        # Should create comprehensive structure analysis
        assert structure is not None
        assert len(structure.root_nodes) >= 2  # Two parts

        # Should identify different hierarchy levels
        parts = [node for node in structure.root_nodes if node.depth == 1]  # Parts
        chapters = [node for node in structure.all_nodes if node.depth == 2]  # Chapters
        sections = [node for node in structure.all_nodes if node.depth == 3]  # Sections

        assert len(parts) >= 2
        assert len(chapters) >= 2
        assert len(sections) >= 2


class TestDirectoryNode:
    """Test the DirectoryNode data model."""

    def test_directory_node_creation(self):
        """Test creating DirectoryNode objects."""
        # This should fail initially (RED phase)

        path = Path("/test/path")
        node = DirectoryNode(
            path=path,
            name="test_name",
            depth=2,
            is_directory=True
        )

        assert node.path == path
        assert node.name == "test_name"
        assert node.depth == 2
        assert node.is_directory == True
        assert node.children == []
        assert node.markdown_files == []

    def test_directory_node_add_child(self):
        """Test adding child nodes to directory nodes."""
        # This should fail initially (RED phase)

        parent = DirectoryNode(Path("/parent"), "parent", 1, True)
        child = DirectoryNode(Path("/parent/child"), "child", 2, True)

        parent.add_child(child)

        assert len(parent.children) == 1
        assert parent.children[0] == child
        assert child.parent == parent

    def test_directory_node_add_markdown_file(self):
        """Test adding markdown files to directory nodes."""
        # This should fail initially (RED phase)

        node = DirectoryNode(Path("/test"), "test", 1, True)
        md_file = Path("/test/file.md")

        node.add_markdown_file(md_file)

        assert len(node.markdown_files) == 1
        assert node.markdown_files[0] == md_file

    def test_directory_node_hierarchy_validation(self):
        """Test that directory node hierarchy is validated."""
        # This should fail initially (RED phase)

        parent = DirectoryNode(Path("/parent"), "parent", 1, True)
        invalid_child = DirectoryNode(Path("/parent/child"), "child", 3, True)  # Skip level 2

        # Should validate hierarchy (or at least not break)
        parent.add_child(invalid_child)

        # Basic structure should still work
        assert len(parent.children) == 1


class TestDirectoryStructureBuilder:
    """Test building comprehensive directory structure representations."""

    def setup_method(self):
        """Set up temporary directory for each test."""
        self.temp_dir = Path(tempfile.mkdtemp())

    def teardown_method(self):
        """Clean up temporary directory after each test."""
        if self.temp_dir.exists():
            shutil.rmtree(self.temp_dir)

    def test_structure_builder_processes_flat_directory(self):
        """Test building structure from flat directory with markdown files."""
        # This should fail initially (RED phase)

        (self.temp_dir / "intro.md").write_text("# Introduction\nIntro content.")
        (self.temp_dir / "chapter_1.md").write_text("# Chapter 1\nChapter content.")
        (self.temp_dir / "conclusion.md").write_text("# Conclusion\nConclusion content.")

        structure = analyze_directory_structure(self.temp_dir)

        # Should process flat structure
        assert structure is not None
        assert len(structure.root_nodes) >= 3

        # All files should be at root level (depth 0)
        for node in structure.root_nodes:
            assert node.depth == 0

    def test_structure_builder_handles_empty_directories(self):
        """Test handling of empty directories in structure."""
        # This should fail initially (RED phase)

        empty_dir = self.temp_dir / "empty_section"
        empty_dir.mkdir()

        structure = analyze_directory_structure(self.temp_dir)

        # Should handle empty directories gracefully
        assert structure is not None
        # Empty directories might be included or excluded depending on implementation

    def test_structure_builder_sorts_items_correctly(self):
        """Test that structure builder sorts items in logical order."""
        # This should fail initially (RED phase)

        # Create files that should be sorted
        (self.temp_dir / "03_chapter_3.md").write_text("# Chapter 3")
        (self.temp_dir / "01_chapter_1.md").write_text("# Chapter 1")
        (self.temp_dir / "02_chapter_2.md").write_text("# Chapter 2")

        structure = analyze_directory_structure(self.temp_dir)

        # Should sort items logically (numeric or alphabetic)
        assert structure is not None
        assert len(structure.root_nodes) == 3

        # Files should be in some logical order
        first_file = structure.root_nodes[0]
        last_file = structure.root_nodes[-1]

        # Should have some ordering (exact order depends on implementation)
        assert first_file.name != last_file.name