#!/bin/bash

# Python Example Demo Script
# Demonstrates the pywasot Python wrapper for the Wasot compiler

set -e  # Exit on any error

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Get the script directory and navigate to project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"

echo -e "${BLUE}🐍 PyWasot Python Wrapper Demo${NC}"
echo "=============================="
echo ""

# Check if we're in the right directory
if [[ ! -f "Cargo.toml" ]] || [[ ! -d "python/pywasot" ]]; then
    echo -e "${RED}❌ Error: Must be run from the wasot project root directory${NC}"
    echo "Expected files: Cargo.toml, python/pywasot/"
    exit 1
fi

# Python virtual environment setup
VENV_DIR="venv"
VENV_PYTHON="$VENV_DIR/bin/python"
VENV_ACTIVATE="$VENV_DIR/bin/activate"

echo -e "${BLUE}🔧 Setting up Python environment...${NC}"

# Create virtual environment if it doesn't exist
if [[ ! -d "$VENV_DIR" ]]; then
    echo "Creating Python virtual environment..."
    python3 -m venv "$VENV_DIR"
fi

# Activate virtual environment
echo "Activating virtual environment..."
source "$VENV_ACTIVATE"

# Check if maturin is installed
if ! command -v maturin &> /dev/null; then
    echo "Installing maturin..."
    pip install maturin
fi

# Check if pywasot is installed or needs rebuilding
NEEDS_BUILD=false

if ! python -c "import pywasot" &> /dev/null; then
    echo "pywasot not found, needs building..."
    NEEDS_BUILD=true
else
    # Check if source files are newer than the last build
    if [[ -f "target/wheels/pywasot-0.1.0-cp"*".whl" ]]; then
        WHEEL_FILE=$(ls -t target/wheels/pywasot-0.1.0-cp*.whl 2>/dev/null | head -n1)
        if [[ -n "$WHEEL_FILE" ]]; then
            # Check if any source files are newer than the wheel
            if find src/ python/ -name "*.rs" -o -name "*.py" | xargs ls -t | head -n1 | xargs stat -c %Y | \
               head -n1 | awk -v wheel_time="$(stat -c %Y "$WHEEL_FILE")" '$1 > wheel_time {exit 0} {exit 1}'; then
                echo "Source files have been modified, rebuilding..."
                NEEDS_BUILD=true
            fi
        else
            NEEDS_BUILD=true
        fi
    else
        NEEDS_BUILD=true
    fi
fi

# Build pywasot if needed
if [[ "$NEEDS_BUILD" == "true" ]]; then
    echo -e "${YELLOW}🔨 Building pywasot...${NC}"
    maturin develop --features python --quiet
    echo -e "${GREEN}✅ Build completed${NC}"
else
    echo -e "${GREEN}✅ pywasot is up to date${NC}"
fi

echo ""
echo -e "${BLUE}🚀 Running Python demos...${NC}"
echo ""

# Demo 1: Facade API - Simple Iterator Pattern
echo -e "${YELLOW}📝 Demo 1: Facade API - Iterator Pattern${NC}"
echo "========================================"

cat > /tmp/demo1.py << 'EOF'
import sys
import os
sys.path.insert(0, os.path.join(os.getcwd(), 'python'))

from pywasot.facade import parse_wasot_string, EventPrinter
from pywasot import BlockStartedEvent, TextEvent, BlockFinishedEvent

# Test with simple Wasot content
wasot_content = """.article title="Python Facade Demo"
This is a demonstration of the new PyWasot facade API.

..section level=1
  Introduction to the simple iterator-based API.
  
  ...code lang="python"
    from pywasot.facade import parse_wasot_string
    
    for event in parse_wasot_string(content):
        print(event)
  ./
./

..footer
  End of facade demo.
./
./"""

print("Parsing Wasot content with facade API:")
print("=" * 50)
print(wasot_content)
print("=" * 50)
print("\nMethod 1: Using EventPrinter (like Rust playground):")
printer = EventPrinter()
printer.process_string(wasot_content)

print("\n\nMethod 2: Custom event handling:")
for event in parse_wasot_string(wasot_content):
    if isinstance(event, BlockStartedEvent):
        meta = event.meta_line
        args = []
        for arg in meta.arguments:
            if hasattr(arg, 'key'):  # KeywordArgument
                args.append(f"{arg.key}={arg.value}")
            else:  # PositionalArgument
                args.append(str(arg.value))
        args_str = f" [{', '.join(args)}]" if args else ""
        print(f"🏷️  Block: {meta.type_name}{args_str}")
    elif isinstance(event, TextEvent):
        for line in event.lines:
            if line.strip():
                print(f"   📄 {line}")
    elif isinstance(event, BlockFinishedEvent):
        print("   🏁 Block ended")
EOF

python /tmp/demo1.py
echo ""

# Demo 2: File parsing with facade API
echo -e "${YELLOW}📁 Demo 2: File Parsing with Facade API${NC}"
echo "========================================"

if [[ -f "examples/demo.wasot" ]]; then
    cat > /tmp/demo2.py << 'EOF'
import sys
import os
sys.path.insert(0, os.path.join(os.getcwd(), 'python'))

from pywasot.facade import parse_wasot_file
from pywasot import BlockStartedEvent, TextEvent, BlockFinishedEvent

# Statistics tracking
blocks = []
text_count = 0

print("Parsing examples/demo.wasot with facade API...")

for event in parse_wasot_file("examples/demo.wasot"):
    if isinstance(event, BlockStartedEvent):
        meta = event.meta_line
        blocks.append({
            'type': meta.type_name,
            'level': meta.level,
            'has_args': len(meta.arguments) > 0,
            'has_inline': bool(meta.inline_text)
        })
    elif isinstance(event, TextEvent):
        text_count += 1

print(f"\n📊 Parsing Summary:")
print(f"   Total blocks: {len(blocks)}")
print(f"   Text chunks: {text_count}")

# Group by type
type_counts = {}
for block in blocks:
    block_type = block['type']
    type_counts[block_type] = type_counts.get(block_type, 0) + 1

print("   Block types:")
for block_type, count in sorted(type_counts.items()):
    print(f"     {block_type}: {count}")

# Show nesting levels
if blocks:
    levels = [block['level'] for block in blocks]
    print(f"   Nesting levels: {min(levels)} to {max(levels)}")
    
    # Count blocks with special features
    with_args = sum(1 for b in blocks if b['has_args'])
    with_inline = sum(1 for b in blocks if b['has_inline'])
    if with_args or with_inline:
        print("   Special features:")
        if with_args:
            print(f"     Blocks with arguments: {with_args}")
        if with_inline:
            print(f"     Blocks with inline text: {with_inline}")
EOF

    python /tmp/demo2.py
else
    echo "⚠ī¸  examples/demo.wasot not found, skipping file demo"
fi

echo ""

# Demo 3: Compare Parser API vs Facade API
echo -e "${YELLOW}🔍 Demo 3: Parser API vs Facade API${NC}"
echo "====================================="

cat > /tmp/demo3.py << 'EOF'
import sys
import os
sys.path.insert(0, os.path.join(os.getcwd(), 'python'))

from pywasot import Parser, KeywordArgument, PositionalArgument
from pywasot.facade import parse_wasot_string
from pywasot import BlockStartedEvent, TextEvent

# Test content with complex arguments
complex_wasot = """.container class="main" id="content" data-role="primary"
Welcome to the comparison demo.

..button type="submit" "Click Me" disabled=true style="color: red"
  Button with mixed arguments.
./

..image src="/path/to/image.jpg" "Alt text" width=800 height=600
./

.."custom element" arg1 "arg with spaces" key="value" flag=true
Custom element with quoted type name.
./
./"""

print("=" * 60)
print("PARSER API (callback-based):")
print("=" * 60)

class ArgumentDemo(Parser):
    def on_block_started(self, event):
        meta = event.meta_line
        print(f"🏷ī¸  Block: {meta.type_name} (level {meta.level})")
        
        if meta.inline_text:
            print(f"   📝 Inline text: '{meta.inline_text}'")
        
        if meta.arguments:
            print(f"   📋 Arguments ({len(meta.arguments)}):")
            for i, arg in enumerate(meta.arguments, 1):
                if isinstance(arg, PositionalArgument):
                    quoted = " (quoted)" if arg.value.quoted else ""
                    print(f"      {i}. Positional: '{arg.value.content}'{quoted}")
                elif isinstance(arg, KeywordArgument):
                    key_quoted = " (quoted)" if arg.key.quoted else ""
                    val_quoted = " (quoted)" if arg.value.quoted else ""
                    print(f"      {i}. Keyword: {arg.key.content}{key_quoted} = '{arg.value.content}'{val_quoted}")
    
    def on_text(self, event):
        non_empty_lines = [line for line in event.lines if line.strip()]
        if non_empty_lines:
            print(f"   📄 Text content: {len(non_empty_lines)} line(s)")
    
    def on_block_finished(self, event):
        pass  # We don't need to show block endings for this demo

demo = ArgumentDemo()
demo.parse_string(complex_wasot)

print("\n" + "=" * 60)
print("FACADE API (iterator-based):")
print("=" * 60)

for event in parse_wasot_string(complex_wasot):
    if isinstance(event, BlockStartedEvent):
        meta = event.meta_line
        print(f"🏷ī¸  Block: {meta.type_name} (level {meta.level})")
        
        if meta.inline_text:
            print(f"   📝 Inline text: '{meta.inline_text}'")
        
        if meta.arguments:
            print(f"   📋 Arguments ({len(meta.arguments)}):")
            for i, arg in enumerate(meta.arguments, 1):
                if hasattr(arg, 'key'):  # KeywordArgument
                    key_quoted = " (quoted)" if arg.key.quoted else ""
                    val_quoted = " (quoted)" if arg.value.quoted else ""
                    print(f"      {i}. Keyword: {arg.key.content}{key_quoted} = '{arg.value.content}'{val_quoted}")
                else:  # PositionalArgument
                    quoted = " (quoted)" if arg.value.quoted else ""
                    print(f"      {i}. Positional: '{arg.value.content}'{quoted}")
    
    elif isinstance(event, TextEvent):
        non_empty_lines = [line for line in event.lines if line.strip()]
        if non_empty_lines:
            print(f"   📄 Text content: {len(non_empty_lines)} line(s)")

print("\nBoth APIs produce the same results!")
EOF

python /tmp/demo3.py
echo ""

# Demo 4: Performance test - Parser vs Facade
echo -e "${YELLOW}⚡ Demo 4: Performance Comparison${NC}"
echo "==================================="

cat > /tmp/demo4.py << 'EOF'
import sys
import os
import time
sys.path.insert(0, os.path.join(os.getcwd(), 'python'))

from pywasot import Parser
from pywasot.facade import parse_wasot_string
from pywasot import BlockStartedEvent, TextEvent

# Generate a large Wasot document
large_doc = ".document\n"
for i in range(100):
    large_doc += f"..section id=\"section-{i}\"\n"
    large_doc += f"  This is section {i} with some content.\n"
    large_doc += f"  \n"
    large_doc += f"  ...subsection level={i % 5}\n"
    large_doc += f"    Subsection content for {i}.\n"
    large_doc += f"    More text here.\n"
    large_doc += f"  ./\n"
    large_doc += f"./\n"
large_doc += "./"

print(f"📏 Document size: {len(large_doc):,} characters")
print(f"   Blocks to process: ~{100 * 2 + 1}")
print()

# Test Parser API
print("Testing Parser API...")

class PerformanceDemo(Parser):
    def __init__(self):
        super().__init__()
        self.block_count = 0
        self.text_count = 0
    
    def on_block_started(self, event):
        self.block_count += 1
    
    def on_text(self, event):
        self.text_count += 1
    
    def on_block_finished(self, event):
        pass

demo = PerformanceDemo()
start_time = time.time()
demo.parse_string(large_doc)
parser_time = time.time() - start_time

print(f"⏱ī¸  Parser API time: {parser_time:.3f} seconds")
print(f"📊 Processed: {demo.block_count} blocks, {demo.text_count} text chunks")

# Test Facade API
print("\nTesting Facade API...")
block_count = 0
text_count = 0

start_time = time.time()
for event in parse_wasot_string(large_doc):
    if isinstance(event, BlockStartedEvent):
        block_count += 1
    elif isinstance(event, TextEvent):
        text_count += 1
facade_time = time.time() - start_time

print(f"⏱ī¸  Facade API time: {facade_time:.3f} seconds")
print(f"📊 Processed: {block_count} blocks, {text_count} text chunks")

# Comparison
print(f"\n🏁 Results:")
print(f"   Parser API: {len(large_doc) / parser_time / 1000:.1f} KB/s")
print(f"   Facade API: {len(large_doc) / facade_time / 1000:.1f} KB/s")
if facade_time < parser_time:
    speedup = (parser_time / facade_time - 1) * 100
    print(f"   Facade API is {speedup:.0f}% faster")
elif parser_time < facade_time:
    speedup = (facade_time / parser_time - 1) * 100
    print(f"   Parser API is {speedup:.0f}% faster")
else:
    print(f"   Both APIs perform equally")
EOF

python /tmp/demo4.py
echo ""

# Cleanup temporary files
rm -f /tmp/demo*.py

echo -e "${GREEN}✅ All demos completed successfully!${NC}"
echo ""
echo -e "${BLUE}📚 Next Steps:${NC}"
echo "   • Install for system-wide use: pip install target/wheels/pywasot-*.whl"
echo "   • See python/pywasot/example.py for more usage examples"
echo "   • Check the Python API documentation in python/pywasot/__init__.py"
echo "   • Use python/pywasot/facade.py for simple iterator-based parsing"
echo ""
echo -e "${YELLOW}🔗 Integration:${NC}"
echo "   The pywasot library offers two APIs:"
echo "   • Parser API: Callback-based for complex event handling"
echo "   • Facade API: Iterator-based for simple event processing (like Rust playground)"
echo ""
echo "   Perfect for:"
echo "   • Document processing pipelines"
echo "   • Static site generators"
echo "   • Content management systems"
echo "   • Text analysis tools"