#!/usr/bin/env python3
"""
Test suite for Wasot selector parsing, StackFrame creation, and specificity calculation.
"""

import pytest
import pywasot


def test_parse_simple_selector():
    """Test parsing a simple type selector."""
    selector = pywasot.parse_selector("paragraph")
    assert selector is not None
    assert str(selector) == "SimpleSelectorGroup(selectors=1)"


def test_parse_complex_selector():
    """Test parsing a complex selector with descendant combinator."""
    selector = pywasot.parse_selector("section paragraph")
    assert selector is not None
    assert str(selector) == "SimpleSelectorGroup(selectors=3)"  # section, combinator, paragraph


def test_parse_invalid_selector():
    """Test that invalid selectors raise errors."""
    with pytest.raises(ValueError) as exc_info:
        pywasot.parse_selector("")
    assert "Failed to parse selector" in str(exc_info.value)


def test_calculate_specificity_simple():
    """Test specificity calculation for a simple selector."""
    selector = pywasot.parse_selector("paragraph")
    specificity = pywasot.calculate_specificity(selector)
    
    assert specificity is not None
    assert specificity.ids == 0
    assert specificity.classes_attributes_pseudos == 0
    assert specificity.types == 1
    assert str(specificity) == "(0,0,1)"


def test_calculate_specificity_with_id():
    """Test specificity calculation for a selector with ID."""
    selector = pywasot.parse_selector("#main")
    specificity = pywasot.calculate_specificity(selector)
    
    assert specificity.ids == 1
    assert specificity.classes_attributes_pseudos == 0
    assert specificity.types == 0
    assert str(specificity) == "(1,0,0)"


def test_calculate_specificity_complex():
    """Test specificity calculation for a complex selector."""
    # Type selector with descendant combinator
    selector = pywasot.parse_selector("article section")
    specificity = pywasot.calculate_specificity(selector)
    
    # Both article and section are type selectors
    assert specificity.ids == 0
    assert specificity.classes_attributes_pseudos == 0
    assert specificity.types == 2
    assert str(specificity) == "(0,0,2)"


def test_parse_metaline():
    """Test parsing a metaline string."""
    metaline = pywasot.parse_metaline(".paragraph .. arg1 key=value :id123", 0)
    
    assert metaline is not None
    assert metaline.type_name == "paragraph"
    assert metaline.level == 1
    assert metaline.line_index == 0
    assert metaline.inline_text == ""
    assert len(metaline.arguments) > 0


def test_parse_metaline_with_inline_text():
    """Test parsing a metaline with inline text."""
    metaline = pywasot.parse_metaline(".heading .. This is inline text", 5)
    
    assert metaline.type_name == "heading"
    assert metaline.level == 1
    assert metaline.line_index == 5
    assert metaline.inline_text == "This is inline text"


def test_parse_metaline_nested():
    """Test parsing a nested metaline."""
    metaline = pywasot.parse_metaline("...deeply.nested", 10)
    
    assert metaline.type_name == "deeply.nested"
    assert metaline.level == 3  # Three dots
    assert metaline.line_index == 10


def test_create_stack_frame():
    """Test creating a StackFrame."""
    metaline = pywasot.parse_metaline(".block", 0)
    stack_frame = pywasot.create_stack_frame(metaline, 2)
    
    assert stack_frame is not None
    assert stack_frame.metaline is metaline
    assert stack_frame.child_index == 2


def test_stack_frame_with_complex_metaline():
    """Test creating a StackFrame with a complex metaline."""
    metaline = pywasot.parse_metaline(".div .. .class1 .class2 id=myid", 42)
    stack_frame = pywasot.create_stack_frame(metaline, 0)
    
    assert stack_frame.metaline.type_name == "div"
    assert stack_frame.metaline.line_index == 42
    assert stack_frame.child_index == 0


def test_specificity_repr():
    """Test the string representation of Specificity."""
    selector = pywasot.parse_selector("div")
    specificity = pywasot.calculate_specificity(selector)
    
    assert repr(specificity) == "Specificity(ids=0, classes_attributes_pseudos=0, types=1)"


def test_selector_group_repr():
    """Test the string representation of SimpleSelectorGroup."""
    selector = pywasot.parse_selector("div p")
    assert repr(selector) == "SimpleSelectorGroup(selectors=3)"


if __name__ == "__main__":
    # Run a simple test to verify the module works
    print("Testing selector parsing...")
    selector = pywasot.parse_selector("section paragraph")
    print(f"Parsed selector: {selector}")
    
    specificity = pywasot.calculate_specificity(selector)
    print(f"Specificity: {specificity}")
    
    metaline = pywasot.parse_metaline(".test .. key=value", 0)
    print(f"Parsed metaline: type={metaline.type_name}, level={metaline.level}")
    
    stack_frame = pywasot.create_stack_frame(metaline, 1)
    print(f"Created StackFrame: child_index={stack_frame.child_index}")
    
    print("\nAll manual tests passed!")