#!/usr/bin/env python3
"""
MaxCpp Phase 35: Test C++ Bulk Find Operations
"""

import time
from cutysoup import CutySoup

def test_bulk_find_operations():
    print("🔍 MaxCpp Phase 35: Testing C++ Bulk Find Operations")
    print("=" * 60)
    
    # Create test HTML with various elements
    html = """
    <html>
        <head>
            <title>Test Page</title>
            <meta charset="utf-8">
            <meta name="description" content="Test page for bulk operations">
        </head>
        <body>
            <div class="container" id="main">
                <h1>Main Title</h1>
                <div class="section">
                    <h2>Section 1</h2>
                    <p class="intro">First paragraph</p>
                    <p class="content">Second paragraph</p>
                    <ul>
                        <li>Item 1</li>
                        <li>Item 2</li>
                        <li>Item 3</li>
                    </ul>
                </div>
                <div class="section">
                    <h2>Section 2</h2>
                    <p class="intro">Another paragraph</p>
                    <div class="nested">
                        <span data-test="value">Test span</span>
                        <a href="http://example.com">Link</a>
                    </div>
                </div>
                <footer>
                    <p>Footer content</p>
                </footer>
            </div>
        </body>
    </html>
    """
    
    soup = CutySoup(html)
    
    # Test basic bulk find operations
    print("Testing C++ bulk find operations:")
    print("-" * 40)
    
    # Check if C++ bulk find methods are available
    has_bulk_methods = hasattr(soup._tree, 'bulk_find_all')
    print(f"✓ C++ bulk find methods available: {has_bulk_methods}")
    
    if has_bulk_methods:
        # Test bulk_find_all with different parameters
        test_cases = [
            # (method_name, args, description)
            ("bulk_find_all", ("p",), "All paragraph elements"),
            ("bulk_find_all", ("div",), "All div elements"),
            ("bulk_find", ("h1",), "First h1 element"),
            ("bulk_find_all", ("", {"class": "section"}), "Elements with class='section'"),
            ("bulk_find_all", ("div", {"class": "container"}), "Div with class='container'"),
            ("bulk_find", ("span", {"data-test": "value"}), "Span with data-test='value'"),
        ]
        
        for method_name, args, description in test_cases:
            try:
                start_time = time.perf_counter()
                
                # Call the C++ method directly
                method = getattr(soup._tree, method_name)
                cpp_results = method(*args)
                
                end_time = time.perf_counter()
                
                # Convert to count for single results
                count = len(cpp_results) if isinstance(cpp_results, list) else (1 if cpp_results else 0)
                
                print(f"✓ {description}: {count} matches ({(end_time - start_time) * 1000:.2f}ms)")
                
                # Show first result details
                if cpp_results:
                    first_result = cpp_results[0] if isinstance(cpp_results, list) else cpp_results
                    tag_name = first_result.get_name()
                    text_preview = first_result.get_text()[:30].replace('\n', ' ').strip()
                    if text_preview:
                        print(f"  First match: <{tag_name}> - '{text_preview}{'...' if len(text_preview) >= 30 else ''}'")
                    else:
                        print(f"  First match: <{tag_name}>")
                
            except Exception as e:
                print(f"✗ {description}: Error - {e}")
    
    print()
    print("Performance comparison:")
    print("-" * 40)
    
    # Compare C++ vs Python performance
    if has_bulk_methods:
        # Test performance of C++ bulk operations vs Python equivalents
        num_iterations = 100
        
        # Test case: find all paragraphs
        print("Finding all paragraph elements:")
        
        # C++ bulk method
        start_time = time.perf_counter()
        for _ in range(num_iterations):
            cpp_results = soup._tree.bulk_find_all("p")
        cpp_time = time.perf_counter() - start_time
        
        # Python method
        start_time = time.perf_counter()
        for _ in range(num_iterations):
            python_results = soup.find_all("p")
        python_time = time.perf_counter() - start_time
        
        cpp_avg = (cpp_time / num_iterations) * 1000
        python_avg = (python_time / num_iterations) * 1000
        speedup = python_avg / cpp_avg if cpp_avg > 0 else 0
        
        print(f"  C++ bulk_find_all:  {cpp_avg:.3f}ms avg ({len(cpp_results)} results)")
        print(f"  Python find_all:    {python_avg:.3f}ms avg ({len(python_results)} results)")
        print(f"  Speedup:           {speedup:.1f}x faster")
        
        # Verify results are equivalent
        if len(cpp_results) == len(python_results):
            print(f"  ✓ Results match: {len(cpp_results)} elements found")
        else:
            print(f"  ⚠ Results differ: C++ found {len(cpp_results)}, Python found {len(python_results)}")
    
    # Test node-scoped bulk operations
    print()
    print("Testing node-scoped bulk find operations:")
    print("-" * 40)
    
    # Get a specific node and test finding within it
    container = soup.find("div", {"class": "container"})
    if container and hasattr(container._node, 'node_find_all'):
        try:
            # Find all paragraphs within the container
            container_paragraphs = container._node.node_find_all("p")
            print(f"✓ Paragraphs in container: {len(container_paragraphs)} found")
            
            # Find first section within container
            first_section = container._node.node_find("div", {"class": "section"})
            if first_section:
                print(f"✓ First section found: <{first_section.get_name()}>")
            else:
                print("✗ First section not found")
                
        except Exception as e:
            print(f"✗ Node-scoped operations error: {e}")
    else:
        print("⚠ Node-scoped bulk operations not available")
    
    print()
    print("🎉 MaxCpp Phase 35: C++ Bulk Find Operations Complete!")

if __name__ == "__main__":
    test_bulk_find_operations()