"""Tests for BlockStartedEvent properties."""

import pytest
import pywasot
from pywasot import (
    BlockStartedEvent, 
    TextEvent, 
    BlockFinishedEvent, 
    Metaline, 
    QuotedString, 
    KeywordArgument, 
    PositionalArgument
)


class TestBlockStartedEventProperties:
    """Test the new properties added to BlockStartedEvent."""
    
    def test_block_type_property(self):
        """Test that block_type returns the correct type name."""
        meta_line = Metaline(
            type_name="paragraph",
            inline_text="",
            level=1
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        assert event.block_type == "paragraph"
    
    def test_inline_text_property(self):
        """Test that inline_text returns the correct inline text."""
        meta_line = Metaline(
            type_name="note",
            inline_text="This is inline text",
            level=1
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        assert event.inline_text == "This is inline text"
    
    def test_args_property_empty(self):
        """Test args property with no positional arguments."""
        meta_line = Metaline(
            type_name="section",
            inline_text="",
            level=1,
            arguments=[]
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        assert event.args == []
    
    def test_args_property_with_positional_args(self):
        """Test args property with positional arguments."""
        positional_args = [
            PositionalArgument(value=QuotedString("arg1", False)),
            PositionalArgument(value=QuotedString("arg2", True)),
            PositionalArgument(value=QuotedString("arg3", False))
        ]
        
        meta_line = Metaline(
            type_name="section",
            inline_text="",
            level=1,
            arguments=positional_args
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        args = event.args
        assert len(args) == 3
        assert args[0] == "arg1"
        assert args[1] == "arg2"
        assert args[2] == "arg3"
    
    def test_args_property_mixed_arguments(self):
        """Test args property with mixed positional and keyword arguments."""
        mixed_args = [
            PositionalArgument(value=QuotedString("pos1", False)),
            KeywordArgument(
                key=QuotedString("key1", False), 
                value=QuotedString("value1", False)
            ),
            PositionalArgument(value=QuotedString("pos2", False)),
            KeywordArgument(
                key=QuotedString("key2", False), 
                value=QuotedString("value2", False)
            )
        ]
        
        meta_line = Metaline(
            type_name="section",
            inline_text="",
            level=1,
            arguments=mixed_args
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        args = event.args
        assert len(args) == 2  # Only positional args
        assert args[0] == "pos1"
        assert args[1] == "pos2"
    
    def test_kwargs_property_empty(self):
        """Test kwargs property with no keyword arguments."""
        meta_line = Metaline(
            type_name="section",
            inline_text="",
            level=1,
            arguments=[]
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        assert event.kwargs == {}
    
    def test_kwargs_property_with_keyword_args(self):
        """Test kwargs property with keyword arguments."""
        keyword_args = [
            KeywordArgument(
                key=QuotedString("importance", False), 
                value=QuotedString("high", False)
            ),
            KeywordArgument(
                key=QuotedString("author", False), 
                value=QuotedString("Alice", True)
            ),
            KeywordArgument(
                key=QuotedString("id", False), 
                value=QuotedString("note-123", False)
            )
        ]
        
        meta_line = Metaline(
            type_name="note",
            inline_text="",
            level=1,
            arguments=keyword_args
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        kwargs = event.kwargs
        assert len(kwargs) == 3
        assert kwargs["importance"] == "high"
        assert kwargs["author"] == "Alice"
        assert kwargs["id"] == "note-123"
    
    def test_kwargs_property_mixed_arguments(self):
        """Test kwargs property with mixed positional and keyword arguments."""
        mixed_args = [
            PositionalArgument(value=QuotedString("pos1", False)),
            KeywordArgument(
                key=QuotedString("key1", False), 
                value=QuotedString("value1", False)
            ),
            PositionalArgument(value=QuotedString("pos2", False)),
            KeywordArgument(
                key=QuotedString("key2", False), 
                value=QuotedString("value2", False)
            )
        ]
        
        meta_line = Metaline(
            type_name="section",
            inline_text="",
            level=1,
            arguments=mixed_args
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        kwargs = event.kwargs
        assert len(kwargs) == 2  # Only keyword args
        assert kwargs["key1"] == "value1"
        assert kwargs["key2"] == "value2"
    
    def test_level_property(self):
        """Test that level property returns the correct level."""
        meta_line = Metaline(
            type_name="subsection",
            inline_text="",
            level=3
        )
        event = BlockStartedEvent(meta_line=meta_line)
        
        assert event.level == 3


class TestBlockStartedEventIntegration:
    """Test BlockStartedEvent properties with real parsing."""
    
    def test_properties_with_parsing_simple_block(self):
        """Test properties work with actual parsed content."""
        wasot_content = ".paragraph\nHello world"
        
        events = list(pywasot.parse_wasot_string(wasot_content))
        
        # Should have BlockStarted, Text, BlockFinished
        assert len(events) >= 1
        assert isinstance(events[0], BlockStartedEvent)
        
        block_event = events[0]
        assert block_event.block_type == "paragraph"
        assert block_event.inline_text == ""
        assert block_event.args == []
        assert block_event.kwargs == {}
        assert block_event.level == 1
    
    def test_properties_with_parsing_block_with_args(self):
        """Test properties work with blocks that have arguments."""
        wasot_content = '.note This is inline text .. Alice importance="high"'
        
        events = list(pywasot.parse_wasot_string(wasot_content))
        
        assert len(events) >= 1
        assert isinstance(events[0], BlockStartedEvent)
        
        block_event = events[0]
        assert block_event.block_type == "note"
        assert block_event.inline_text == "This is inline text "
        assert block_event.level == 1
        
        # Check args and kwargs
        args = block_event.args
        kwargs = block_event.kwargs
        
        # Should have positional arg "Alice" and keyword arg importance="high"
        assert len(args) == 1
        assert args[0] == "Alice"
        
        assert len(kwargs) == 1
        assert "importance" in kwargs
        assert kwargs["importance"] == "high"
    
    def test_properties_with_parsing_nested_blocks(self):
        """Test properties work with nested blocks."""
        wasot_content = """.section
..subsection .. title="Nested"
Text content
../
./"""
        
        events = list(pywasot.parse_wasot_string(wasot_content))
        
        # Find the section and subsection events
        section_event = None
        subsection_event = None
        
        for event in events:
            if isinstance(event, BlockStartedEvent):
                if event.block_type == "section":
                    section_event = event
                elif event.block_type == "subsection":
                    subsection_event = event
        
        assert section_event is not None
        assert subsection_event is not None
        
        # Test section properties
        assert section_event.block_type == "section"
        assert section_event.level == 1
        assert section_event.args == []
        assert section_event.kwargs == {}
        
        # Test subsection properties
        assert subsection_event.block_type == "subsection"
        assert subsection_event.level == 2
        
        # Check subsection kwargs
        kwargs = subsection_event.kwargs
        assert len(kwargs) == 1
        assert "title" in kwargs
        assert kwargs["title"] == "Nested"


if __name__ == "__main__":
    pytest.main([__file__])