// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

// Test file for recursive namespace etcd_path functionality
#[allow(unused_imports)]
use dynamo_runtime::{DistributedRuntime, Runtime};

#[cfg(feature = "integration")]
#[test]
fn test_namespace_etcd_path_format() {
    // Test that the etcd_path format is correct for the expected use case
    // This test verifies the format: dynamo://ns1.ns2.ns3/component/{component.name()}

    // Expected format examples:
    let single_ns_path = "dynamo://ns1";
    let nested_ns_path = "dynamo://ns1.ns2.ns3";
    let component_path = "dynamo://ns1.ns2.ns3/_component_/my-component";

    // Verify the format matches our requirements
    assert!(single_ns_path.starts_with("dynamo://"));
    assert!(nested_ns_path.starts_with("dynamo://"));
    assert!(nested_ns_path.contains("."));
    assert!(component_path.contains("/_component_/"));

    // Test the specific format requested in the user query (now with reserved keywords)
    let expected_format = "dynamo://ns1.ns2.ns3/_component_/my-component";
    assert_eq!(component_path, expected_format);

    println!("✅ Namespace etcd_path format verification passed");
    println!("   Single namespace: {}", single_ns_path);
    println!("   Nested namespace: {}", nested_ns_path);
    println!("   Component path: {}", component_path);
}

#[cfg(feature = "integration")]
#[tokio::test]
async fn test_recursive_namespace_implementation() {
    use dynamo_runtime::{
        distributed::DistributedConfig, storage::key_value_store::KeyValueStoreSelect,
        transports::nats,
    };

    let runtime = Runtime::from_current().unwrap();
    let config = DistributedConfig {
        store_backend: KeyValueStoreSelect::Memory,
        nats_config: Some(nats::ClientOptions::default()),
        request_plane: dynamo_runtime::distributed::RequestPlaneMode::default(),
    };
    let distributed_runtime = DistributedRuntime::new(runtime, config).await.unwrap();

    // Test single namespace
    let ns1 = distributed_runtime.namespace("ns1").unwrap();
    assert_eq!(ns1.etcd_path(), "dynamo://ns1");
    assert_eq!(ns1.name(), "ns1");

    // Test nested namespace ns1.ns2
    let ns2 = ns1.namespace("ns2").unwrap();
    assert_eq!(ns2.etcd_path(), "dynamo://ns1.ns2");
    assert_eq!(ns2.name(), "ns1.ns2");

    // Test deeply nested namespace ns1.ns2.ns3
    let ns3 = ns2.namespace("ns3").unwrap();
    assert_eq!(ns3.etcd_path(), "dynamo://ns1.ns2.ns3");
    assert_eq!(ns3.name(), "ns1.ns2.ns3");

    // Test component in deeply nested namespace
    let component = ns3.component("my-component").unwrap();
    assert_eq!(
        component.etcd_path().to_string(),
        "dynamo://ns1.ns2.ns3/_component_/my-component"
    );
    assert_eq!(component.name(), "my-component");
    assert_eq!(component.path(), "ns1.ns2.ns3/my-component");

    println!("✅ Actual recursive namespace implementation test passed!");
    println!("   Root namespace: {}", ns1.etcd_path());
    println!("   Nested namespace: {}", ns2.etcd_path());
    println!("   Deep namespace: {}", ns3.etcd_path());
    println!("   Component path: {}", component.etcd_path());
}

#[cfg(feature = "integration")]
#[tokio::test]
async fn test_multiple_branches_recursive_namespaces() {
    use dynamo_runtime::{
        distributed::DistributedConfig, storage::key_value_store::KeyValueStoreSelect,
        transports::nats,
    };

    let runtime = Runtime::from_current().unwrap();
    let config = DistributedConfig {
        store_backend: KeyValueStoreSelect::Memory,
        nats_config: Some(nats::ClientOptions::default()),
        request_plane: dynamo_runtime::distributed::RequestPlaneMode::default(),
    };
    let distributed_runtime = DistributedRuntime::new(runtime, config).await.unwrap();

    // Create root namespace
    let root = distributed_runtime.namespace("root").unwrap();

    // Create multiple branches
    let prod_ns = root.namespace("prod").unwrap();
    let staging_ns = root.namespace("staging").unwrap();

    // Create services in each branch
    let prod_service_ns = prod_ns.namespace("services").unwrap();
    let staging_service_ns = staging_ns.namespace("services").unwrap();

    // Verify the paths are correct
    assert_eq!(prod_service_ns.etcd_path(), "dynamo://root.prod.services");
    assert_eq!(
        staging_service_ns.etcd_path(),
        "dynamo://root.staging.services"
    );

    // Create components in each branch
    let prod_component = prod_service_ns.component("api-gateway").unwrap();
    let staging_component = staging_service_ns.component("api-gateway").unwrap();

    assert_eq!(
        prod_component.etcd_path().to_string(),
        "dynamo://root.prod.services/_component_/api-gateway"
    );
    assert_eq!(
        staging_component.etcd_path().to_string(),
        "dynamo://root.staging.services/_component_/api-gateway"
    );

    // Verify they are different
    assert_ne!(prod_component.etcd_path(), staging_component.etcd_path());

    println!("✅ Multiple branches recursive namespaces test passed!");
    println!("   Production: {}", prod_component.etcd_path());
    println!("   Staging: {}", staging_component.etcd_path());
}
