use std::collections::HashMap;
use ocg::{execute_with_params, CypherValue, PropertyGraph};

#[test]
fn test_starts_with() {
    let mut graph = PropertyGraph::new();
    let params = HashMap::new();

    println!("\n=== Test startsWith() ===");

    // Positive test
    let result = execute_with_params(
        &mut graph,
        "RETURN startsWith('hello world', 'hello') AS result",
        params.clone()
    ).unwrap();
    println!("startsWith('hello world', 'hello'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(true)));

    // Negative test
    let result = execute_with_params(
        &mut graph,
        "RETURN startsWith('hello world', 'world') AS result",
        params.clone()
    ).unwrap();
    println!("startsWith('hello world', 'world'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(false)));

    // NULL test
    let result = execute_with_params(
        &mut graph,
        "RETURN startsWith(null, 'hello') AS result",
        params.clone()
    ).unwrap();
    println!("startsWith(null, 'hello'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Null));
}

#[test]
fn test_ends_with() {
    let mut graph = PropertyGraph::new();
    let params = HashMap::new();

    println!("\n=== Test endsWith() ===");

    // Positive test
    let result = execute_with_params(
        &mut graph,
        "RETURN endsWith('hello world', 'world') AS result",
        params.clone()
    ).unwrap();
    println!("endsWith('hello world', 'world'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(true)));

    // Negative test
    let result = execute_with_params(
        &mut graph,
        "RETURN endsWith('hello world', 'hello') AS result",
        params.clone()
    ).unwrap();
    println!("endsWith('hello world', 'hello'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(false)));

    // NULL test
    let result = execute_with_params(
        &mut graph,
        "RETURN endsWith('hello', null) AS result",
        params.clone()
    ).unwrap();
    println!("endsWith('hello', null): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Null));
}

#[test]
fn test_contains() {
    let mut graph = PropertyGraph::new();
    let params = HashMap::new();

    println!("\n=== Test contains() ===");

    // Positive test
    let result = execute_with_params(
        &mut graph,
        "RETURN contains('hello world', 'lo wo') AS result",
        params.clone()
    ).unwrap();
    println!("contains('hello world', 'lo wo'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(true)));

    // Negative test
    let result = execute_with_params(
        &mut graph,
        "RETURN contains('hello world', 'xyz') AS result",
        params.clone()
    ).unwrap();
    println!("contains('hello world', 'xyz'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(false)));

    // NULL test
    let result = execute_with_params(
        &mut graph,
        "RETURN contains(null, 'hello') AS result",
        params.clone()
    ).unwrap();
    println!("contains(null, 'hello'): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Null));

    // Empty string test
    let result = execute_with_params(
        &mut graph,
        "RETURN contains('hello', '') AS result",
        params.clone()
    ).unwrap();
    println!("contains('hello', ''): {:?}", result.rows[0].get("result"));
    assert_eq!(result.rows[0].get("result"), Some(&CypherValue::Boolean(true)));
}

#[test]
fn test_all_three_together() {
    let mut graph = PropertyGraph::new();
    let params = HashMap::new();

    println!("\n=== Test all three functions together ===");

    let result = execute_with_params(
        &mut graph,
        "RETURN
            startsWith('hello world', 'hello') AS starts,
            endsWith('hello world', 'world') AS ends,
            contains('hello world', 'lo wo') AS cont",
        params
    ).unwrap();

    println!("Result: {:?}", result.rows[0]);
    assert_eq!(result.rows[0].get("starts"), Some(&CypherValue::Boolean(true)));
    assert_eq!(result.rows[0].get("ends"), Some(&CypherValue::Boolean(true)));
    assert_eq!(result.rows[0].get("cont"), Some(&CypherValue::Boolean(true)));
}
