#!/usr/bin/env herodo
// 01_container_operations.rhai
// Tests for Nerdctl container operations

// Custom assert function
fn assert_true(condition, message) {
    if !condition {
        print(`ASSERTION FAILED: ${message}`);
        throw message;
    }
}

// Custom assert_eq function
fn assert_eq(actual, expected, message) {
    if actual != expected {
        print(`ASSERTION FAILED: ${message}`);
        print(`Expected: "${expected}"`);
        print(`Actual: "${actual}"`);
        throw message;
    }
}

// Helper function to check if nerdctl is available
fn is_nerdctl_available() {
    try {
        let result = run("which nerdctl");
        return result.success;
    } catch(err) {
        return false;
    }
}

// Helper function to check if a container exists
fn container_exists(container_name) {
    try {
        let result = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`);
        return result.success;
    } catch(err) {
        return false;
    }
}

// Helper function to clean up a container if it exists
fn cleanup_container(container_name) {
    if container_exists(container_name) {
        try {
            run(`nerdctl stop ${container_name}`);
            run(`nerdctl rm ${container_name}`);
            print(`Cleaned up container: ${container_name}`);
        } catch(err) {
            print(`Error cleaning up container ${container_name}: ${err}`);
        }
    }
}

print("=== Testing Nerdctl Container Operations ===");

// Check if nerdctl is available
let nerdctl_available = is_nerdctl_available();
if !nerdctl_available {
    print("nerdctl is not available. Skipping Nerdctl tests.");
    // Exit gracefully without error
    return;
}

print("✓ nerdctl is available");

// Define test container name
let container_name = "rhai_test_container";

// Clean up any existing test container
cleanup_container(container_name);

try {
    // Test creating a new Container
    print("Testing nerdctl_container_new()...");
    let container = nerdctl_container_new(container_name);
    
    // Test Container properties
    print("Testing Container properties...");
    assert_eq(container.name, container_name, "Container name should match");
    assert_eq(container.container_id, "", "Container ID should be empty initially");
    
    // Test setting container image
    print("Testing with_image()...");
    container.with_image("alpine:latest");
    assert_eq(container.image, "alpine:latest", "Container image should match");
    
    // Test setting detach mode
    print("Testing with_detach()...");
    container.with_detach(true);
    assert_true(container.detach, "Container detach mode should be true");
    
    // Test setting environment variables
    print("Testing with_env()...");
    container.with_env("TEST_VAR", "test_value");
    
    // Test setting multiple environment variables
    print("Testing with_envs()...");
    let env_map = #{
        "VAR1": "value1",
        "VAR2": "value2"
    };
    container.with_envs(env_map);
    
    // Test setting ports
    print("Testing with_port()...");
    container.with_port("8080:80");
    
    // Test setting multiple ports
    print("Testing with_ports()...");
    container.with_ports(["9090:90", "7070:70"]);
    
    // Test setting volumes
    print("Testing with_volume()...");
    // Create a test directory for volume mounting
    let test_dir = "rhai_test_nerdctl_volume";
    mkdir(test_dir);
    container.with_volume(`${test_dir}:/data`);
    
    // Test setting resource limits
    print("Testing with_cpu_limit() and with_memory_limit()...");
    container.with_cpu_limit("0.5");
    container.with_memory_limit("256m");
    
    // Test running the container
    print("Testing run()...");
    let run_result = container.run();
    assert_true(run_result.success, "Container run should succeed");
    assert_true(container.container_id != "", "Container ID should not be empty after run");
    print(`✓ run(): Container started with ID: ${container.container_id}`);
    
    // Test executing a command in the container
    print("Testing exec()...");
    let exec_result = container.exec("echo 'Hello from container'");
    assert_true(exec_result.success, "Container exec should succeed");
    assert_true(exec_result.stdout.contains("Hello from container"), "Exec output should contain expected text");
    print("✓ exec(): Command executed successfully");
    
    // Test getting container logs
    print("Testing logs()...");
    let logs_result = container.logs();
    assert_true(logs_result.success, "Container logs should succeed");
    print("✓ logs(): Logs retrieved successfully");
    
    // Test stopping the container
    print("Testing stop()...");
    let stop_result = container.stop();
    assert_true(stop_result.success, "Container stop should succeed");
    print("✓ stop(): Container stopped successfully");
    
    // Test removing the container
    print("Testing remove()...");
    let remove_result = container.remove();
    assert_true(remove_result.success, "Container remove should succeed");
    print("✓ remove(): Container removed successfully");
    
    // Clean up test directory
    delete(test_dir);
    print("✓ Cleanup: Test directory removed");
    
    print("All container operations tests completed successfully!");
} catch(err) {
    print(`Error: ${err}`);
    
    // Clean up in case of error
    cleanup_container(container_name);
    
    // Clean up test directory
    try {
        delete("rhai_test_nerdctl_volume");
    } catch(e) {
        // Ignore errors during cleanup
    }
    
    throw err;
}
