"""Unit tests for HeadingStack."""

from __future__ import annotations

from extractor.heading_stack import HeadingStack


class TestHeadingStack:
    def test_empty_stack_returns_empty_path(self):
        stack = HeadingStack()
        assert stack.current_section_path() == []

    def test_push_single_heading(self):
        stack = HeadingStack()
        stack.push(level=1, text="Introduction")
        assert stack.current_section_path() == ["Introduction"]

    def test_push_nested_headings(self):
        stack = HeadingStack()
        stack.push(level=1, text="Chapter 1")
        stack.push(level=2, text="Section 1.1")
        stack.push(level=3, text="Subsection 1.1.1")
        assert stack.current_section_path() == ["Chapter 1", "Section 1.1", "Subsection 1.1.1"]

    def test_same_level_replaces(self):
        stack = HeadingStack()
        stack.push(level=1, text="Chapter 1")
        stack.push(level=1, text="Chapter 2")
        assert stack.current_section_path() == ["Chapter 2"]

    def test_shallower_level_pops_deeper(self):
        stack = HeadingStack()
        stack.push(level=1, text="Chapter 1")
        stack.push(level=2, text="Section 1.1")
        stack.push(level=3, text="Subsection 1.1.1")
        stack.push(level=2, text="Section 1.2")
        assert stack.current_section_path() == ["Chapter 1", "Section 1.2"]

    def test_skip_level_heading(self):
        """h1 → h3 skip (heading level jumps) should work correctly."""
        stack = HeadingStack()
        stack.push(level=1, text="Title")
        stack.push(level=3, text="Deep Section")  # skip level 2
        assert stack.current_section_path() == ["Title", "Deep Section"]

    def test_reset_clears_stack(self):
        stack = HeadingStack()
        stack.push(level=1, text="Chapter 1")
        stack.push(level=2, text="Section 1.1")
        stack.reset()
        assert stack.current_section_path() == []

    def test_depth_is_not_tier(self):
        """section_path_tier is detection quality, not stack depth."""
        stack = HeadingStack(detection_tier=1)
        stack.push(level=1, text="H1", detection_tier=1)
        stack.push(level=2, text="H2", detection_tier=1)
        stack.push(level=3, text="H3", detection_tier=1)
        # Tier should be 1 (quality), not 3 (depth)
        assert stack.current_section_path_tier() == 1
        assert stack.depth() == 3  # depth is 3

    def test_tier_follows_detection_quality(self):
        """When a heuristic heading is detected, tier reflects that."""
        stack = HeadingStack(detection_tier=1)
        stack.push(level=1, text="Chapter 1", detection_tier=1)  # native
        stack.push(level=2, text="BIG BOLD TEXT", detection_tier=2)  # font heuristic
        assert stack.current_section_path_tier() == 2

    def test_tier_falls_back_to_document_baseline(self):
        """Empty stack returns document baseline tier."""
        stack = HeadingStack(detection_tier=3)
        assert stack.current_section_path_tier() == 3

    def test_subtitle_does_not_affect_stack(self):
        """structural:subtitle has heading_level=None and must not be pushed."""
        stack = HeadingStack()
        stack.push(level=1, text="Document Title")
        # subtitle has heading_level=None, so caller never pushes it
        # Stack should remain unchanged
        assert stack.current_section_path() == ["Document Title"]
        assert stack.depth() == 1
