//! Test UPDATE/SET operations with NetworKitRust backend.
//! These operations rely on get_node_mut() and get_edge_mut() working correctly.

use ocg::{execute, graph::NetworKitRustBackend};

#[test]
fn test_set_node_property() {
    let mut backend = NetworKitRustBackend::new();

    // Create a node
    execute(&mut backend, "CREATE (n:Person {name: 'Alice'})").unwrap();

    // Set a new property
    let result = execute(&mut backend, "MATCH (n:Person) SET n.age = 30 RETURN n.name, n.age").unwrap();

    assert_eq!(result.rows.len(), 1);
    let row = &result.rows[0];
    assert_eq!(row.get("n.name").unwrap().to_string(), "'Alice'");
    assert_eq!(row.get("n.age").unwrap().to_string(), "30");
}

#[test]
fn test_set_multiple_properties() {
    let mut backend = NetworKitRustBackend::new();

    // Create a node
    execute(&mut backend, "CREATE (n:Person {name: 'Bob'})").unwrap();

    // Set multiple properties
    let result = execute(
        &mut backend,
        "MATCH (n:Person) SET n.age = 25, n.city = 'NYC' RETURN n.name, n.age, n.city",
    )
    .unwrap();

    assert_eq!(result.rows.len(), 1);
    let row = &result.rows[0];
    assert_eq!(row.get("n.name").unwrap().to_string(), "'Bob'");
    assert_eq!(row.get("n.age").unwrap().to_string(), "25");
    assert_eq!(row.get("n.city").unwrap().to_string(), "'NYC'");
}

#[test]
fn test_set_relationship_property() {
    let mut backend = NetworKitRustBackend::new();

    // Create nodes and relationship separately
    execute(&mut backend, "CREATE (a:Person {name: 'Alice'})").unwrap();
    execute(&mut backend, "CREATE (b:Person {name: 'Bob'})").unwrap();
    execute(
        &mut backend,
        "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[r:KNOWS]->(b)",
    )
    .unwrap();

    // Set property on relationship
    let result = execute(
        &mut backend,
        "MATCH (a:Person)-[r:KNOWS]->(b:Person) SET r.since = 2020 RETURN r.since",
    )
    .unwrap();

    assert_eq!(result.rows.len(), 1);
    let row = &result.rows[0];
    assert_eq!(row.get("r.since").unwrap().to_string(), "2020");
}

#[test]
fn test_remove_property() {
    let mut backend = NetworKitRustBackend::new();

    // Create a node with properties
    execute(
        &mut backend,
        "CREATE (n:Person {name: 'Charlie', age: 35, city: 'LA'})",
    )
    .unwrap();

    // Remove a property
    let result = execute(
        &mut backend,
        "MATCH (n:Person) REMOVE n.age RETURN n.name, n.city, n.age",
    )
    .unwrap();

    assert_eq!(result.rows.len(), 1);
    let row = &result.rows[0];
    assert_eq!(row.get("n.name").unwrap().to_string(), "'Charlie'");
    assert_eq!(row.get("n.city").unwrap().to_string(), "'LA'");
    assert_eq!(row.get("n.age").unwrap().to_string(), "null");
}

#[test]
fn test_update_property_in_same_query() {
    let mut backend = NetworKitRustBackend::new();

    // Create a node
    execute(&mut backend, "CREATE (n:Counter {value: 0})").unwrap();

    // Update and return in same query
    let result = execute(
        &mut backend,
        "MATCH (n:Counter) SET n.value = n.value + 1 RETURN n.value",
    )
    .unwrap();

    assert_eq!(result.rows.len(), 1);
    assert_eq!(result.rows[0].get("n.value").unwrap().to_string(), "1");
}

#[test]
fn test_multiple_updates_same_node() {
    let mut backend = NetworKitRustBackend::new();

    // Create a node
    execute(&mut backend, "CREATE (n:Test {x: 1})").unwrap();

    // Multiple updates
    execute(&mut backend, "MATCH (n:Test) SET n.x = 2").unwrap();
    execute(&mut backend, "MATCH (n:Test) SET n.x = 3").unwrap();
    execute(&mut backend, "MATCH (n:Test) SET n.x = 4").unwrap();

    // Verify final value
    let result = execute(&mut backend, "MATCH (n:Test) RETURN n.x").unwrap();
    assert_eq!(result.rows.len(), 1);
    assert_eq!(result.rows[0].get("n.x").unwrap().to_string(), "4");
}
