// tests/edge_cases.rs

use axioma::prelude::*;

#[test]
fn test_true_nightmare_edge_cases_and_topology() {
    // Highly irregular but syntactically valid JSON edge cases.
    // Tests empty keys, whitespace keys, multidimensional empty arrays,
    // and trailing commas in nested mixed structures.
    let engine = axioma!({
        "empty_keys": {
            "": [ null, { "": [] } ]
        },
        "whitespace_keys": {
            "   ": {
                "\n": [ [ [ ] ] ],
                "null": null
            }
        },
        "trailing_commas": [
            { "a": 1, },
            [ 2, ],
        ],
    });

    // ========================================================================
    // 2D Space Mapping & NodeKind Tracking
    // Kinds: 1=ObjKey, 2=ObjValue, 3=ArrItem, 4=EmptyObj, 5=EmptyArr
    // ========================================================================
    // (r, c)
    // (0,0): "empty_keys" (next_c=2) -> (1,0): "" (next_c=2)
    //                                          -> (2,0): null
    //                                          -> (2,1): "" -> (3,1): [] (EmptyArr)
    //
    // (0,2): "whitespace_keys" (next_c=4) -> (1,2): "   " (next_c=4)
    //                                               -> (2,2): "\n"   -> (3,2): [] (EmptyArr)
    //                                               -> (2,3): "null" -> (3,3): null
    //
    // (0,4): "trailing_commas" (next_c=6) -> (1,4): "a" -> (2,4): 1
    //                                     -> (1,5): 2
    // ========================================================================

    // 1. Empty Keys Block (c=0, c=1)
    let (k_empty_keys, next_c_0, v_empty_keys) = engine(0, 0);
    assert_eq!(k_empty_keys, 1);
    assert_eq!(next_c_0, 2); // Skips entirely to c=2
    assert_eq!(v_empty_keys, AxiValue::Str("empty_keys"));

    let (k_empty_str, _, v_empty_str) = engine(1, 0);
    assert_eq!(k_empty_str, 1);
    assert_eq!(v_empty_str, AxiValue::Str(""));

    let (k_null_item, _, v_null_item) = engine(2, 0);
    assert_eq!(k_null_item, 3); // 3 = Array Item
    assert_eq!(v_null_item, AxiValue::Null);

    let (k_empty_str_inner, _, v_empty_str_inner) = engine(2, 1);
    assert_eq!(k_empty_str_inner, 1);
    assert_eq!(v_empty_str_inner, AxiValue::Str(""));

    let (k_empty_arr, _, v_empty_arr) = engine(3, 1);
    assert_eq!(k_empty_arr, 5); // 5 = EmptyArr
    assert_eq!(v_empty_arr, AxiValue::Null);

    // 2. Whitespace Keys Block (c=2, c=3)
    let (_, next_c_2, v_ws_keys) = engine(0, 2);
    assert_eq!(next_c_2, 4); // Skips entirely to c=4
    assert_eq!(v_ws_keys, AxiValue::Str("whitespace_keys"));

    assert_eq!(engine(1, 2).2, AxiValue::Str("   "));
    assert_eq!(engine(2, 2).2, AxiValue::Str("\n"));

    // Deeply nested empty array `[[[]]]` does not increment depth beyond the innermost evaluation
    let (k_deep_arr, _, v_deep_arr) = engine(3, 2);
    assert_eq!(k_deep_arr, 5); // 5 = EmptyArr
    assert_eq!(v_deep_arr, AxiValue::Null);

    // Key named "null" pointing to actual null
    assert_eq!(engine(2, 3).2, AxiValue::Str("null"));
    let (k_actual_null, _, v_actual_null) = engine(3, 3);
    assert_eq!(k_actual_null, 2); // 2 = Object Value
    assert_eq!(v_actual_null, AxiValue::Null);

    // 3. Trailing Commas Block (c=4, c=5)
    let (_, next_c_4, v_trailing) = engine(0, 4);
    assert_eq!(next_c_4, 6); // Skips to EOF (c=6)
    assert_eq!(v_trailing, AxiValue::Str("trailing_commas"));

    // Object with trailing comma inside array
    assert_eq!(engine(1, 4).2, AxiValue::Str("a"));
    let (k_one, _, v_one) = engine(2, 4);
    assert_eq!(k_one, 2); // 2 = Object Value
    assert_eq!(v_one, AxiValue::Num("1"));

    // Array with trailing comma inside array
    let (k_two, _, v_two) = engine(1, 5);
    assert_eq!(k_two, 3); // 3 = Array Item
    assert_eq!(v_two, AxiValue::Num("2"));

    // Out of bounds check
    assert_eq!(engine(0, 6).2, AxiValue::Null);
}
