"""
Test bulk loader API
"""
import sys
import os

# Add parent directory to path for local testing
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

try:
    from ocg import Graph
    HAS_OCG = True
except ImportError:
    HAS_OCG = False
    print("OCG not installed - skipping bulk loader tests")


def test_create_node():
    """Test create_node method"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Create single node
    node_id = graph.create_node(["Person"], {"name": "Alice", "age": 30})
    assert isinstance(node_id, int)
    assert node_id >= 1

    # Verify node exists via OpenCypher
    result = graph.execute("MATCH (n:Person {name: 'Alice'}) RETURN n.age AS age")
    assert len(result) == 1
    assert result[0]['age'] == 30

    print("✓ create_node() works!")


def test_create_relationship():
    """Test create_relationship method"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Create nodes
    node1 = graph.create_node(["Person"], {"name": "Alice"})
    node2 = graph.create_node(["Person"], {"name": "Bob"})

    # Create relationship
    edge_id = graph.create_relationship(node1, node2, "KNOWS", {"since": 2020})
    assert isinstance(edge_id, int)
    assert edge_id >= 1

    # Verify relationship exists via OpenCypher
    result = graph.execute("""
        MATCH (a:Person)-[r:KNOWS]->(b:Person)
        RETURN a.name AS from, b.name AS to, r.since AS since
    """)
    assert len(result) == 1
    assert result[0]['from'] == "Alice"
    assert result[0]['to'] == "Bob"
    assert result[0]['since'] == 2020

    print("✓ create_relationship() works!")


def test_bulk_create_nodes():
    """Test bulk_create_nodes method"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Bulk create nodes
    nodes = [
        (["Person"], {"name": "Alice", "age": 30}),
        (["Person"], {"name": "Bob", "age": 25}),
        (["Person"], {"name": "Charlie", "age": 35}),
        (["Person", "Employee"], {"name": "Diana", "age": 28, "dept": "Engineering"}),
    ]

    node_ids = graph.bulk_create_nodes(nodes)

    assert len(node_ids) == 4
    assert all(isinstance(nid, int) for nid in node_ids)
    assert all(nid >= 1 for nid in node_ids)

    # Verify nodes exist via OpenCypher
    result = graph.execute("MATCH (n:Person) RETURN count(n) AS count")
    assert result[0]['count'] == 4

    # Verify multi-label node
    result = graph.execute("MATCH (n:Person:Employee) RETURN n.name AS name")
    assert len(result) == 1
    assert result[0]['name'] == "Diana"

    print(f"✓ bulk_create_nodes() created {len(node_ids)} nodes!")


def test_bulk_create_relationships():
    """Test bulk_create_relationships method"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Create nodes first
    nodes = [
        (["Person"], {"name": f"Person{i}"})
        for i in range(10)
    ]
    node_ids = graph.bulk_create_nodes(nodes)

    # Bulk create relationships
    relationships = [
        (node_ids[i], node_ids[i+1], "KNOWS", {"weight": float(i)})
        for i in range(9)
    ]

    edge_ids = graph.bulk_create_relationships(relationships)

    assert len(edge_ids) == 9
    assert all(isinstance(eid, int) for eid in edge_ids)

    # Verify relationships exist
    result = graph.execute("MATCH ()-[r:KNOWS]->() RETURN count(r) AS count")
    assert result[0]['count'] == 9

    print(f"✓ bulk_create_relationships() created {len(edge_ids)} edges!")


def test_performance_comparison():
    """Compare bulk loader vs OpenCypher performance"""
    if not HAS_OCG:
        return

    import time

    # Test 1: OpenCypher CREATE (current method)
    graph1 = Graph()
    start = time.time()
    for i in range(100):
        graph1.execute(f"CREATE (n:Person {{id: {i}, name: 'Person{i}'}})")
    cypher_time = time.time() - start

    # Test 2: Bulk loader (new method)
    graph2 = Graph()
    nodes = [
        (["Person"], {"id": i, "name": f"Person{i}"})
        for i in range(100)
    ]
    start = time.time()
    graph2.bulk_create_nodes(nodes)
    bulk_time = time.time() - start

    # Calculate speedup
    speedup = cypher_time / bulk_time if bulk_time > 0 else float('inf')

    print(f"\n📊 Performance Comparison (100 nodes):")
    print(f"  OpenCypher CREATE: {cypher_time*1000:.2f}ms")
    print(f"  Bulk Loader:   {bulk_time*1000:.2f}ms")
    print(f"  Speedup:       {speedup:.1f}x faster!")

    # Verify both graphs have same number of nodes
    assert graph1.node_count() == graph2.node_count() == 100


def test_empty_properties():
    """Test creating nodes/edges without properties"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Node without properties
    node1 = graph.create_node(["Label1"])
    assert isinstance(node1, int)

    # Relationship without properties
    node2 = graph.create_node(["Label2"])
    edge1 = graph.create_relationship(node1, node2, "REL_TYPE")
    assert isinstance(edge1, int)

    print("✓ Empty properties work!")


def test_complex_properties():
    """Test creating nodes with complex property types"""
    if not HAS_OCG:
        return

    graph = Graph()

    # Complex properties
    node_id = graph.create_node(
        ["Person"],
        {
            "name": "Alice",
            "age": 30,
            "score": 95.5,
            "active": True,
            "tags": ["python", "rust", "graph"],
            "metadata": {"city": "NYC", "country": "USA"},
        }
    )

    # Verify via OpenCypher
    result = graph.execute("MATCH (n:Person {name: 'Alice'}) RETURN n")
    assert len(result) == 1
    node = result[0]['n']
    assert node['properties']['age'] == 30
    assert node['properties']['score'] == 95.5
    assert node['properties']['active'] == True
    assert node['properties']['tags'] == ["python", "rust", "graph"]

    print("✓ Complex properties work!")


if __name__ == "__main__":
    if not HAS_OCG:
        print("Please install OCG first:")
        print("  maturin develop --features python")
        sys.exit(1)

    print("Testing Bulk Loader API...\n")

    test_create_node()
    test_create_relationship()
    test_bulk_create_nodes()
    test_bulk_create_relationships()
    test_empty_properties()
    test_complex_properties()
    test_performance_comparison()

    print("\n✅ All bulk loader tests passed!")
