#!/usr/bin/env nu

# Service Management System Tests

use ../lib_provisioning/services/mod.nu *

# Test service registry loading
export def test-service-registry-loading [] {
    print "Testing: Service registry loading"

    # Load and validate registry (no try-catch)
    let result = (do {
        let registry = (load-service-registry)

        assert ($registry | is-not-empty) "Registry should not be empty"
        assert ("orchestrator" in ($registry | columns)) "Orchestrator should be in registry"

        print "✅ Service registry loads correctly"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Failed to load service registry"
        false
    }
}

# Test service definition retrieval
export def test-service-definition [] {
    print "Testing: Service definition retrieval"

    # Get and validate service definition (no try-catch)
    let result = (do {
        let orchestrator = (get-service-definition "orchestrator")

        assert ($orchestrator.name == "orchestrator") "Service name should match"
        assert ($orchestrator.type == "platform") "Service type should be platform"
        assert ($orchestrator.deployment.mode == "binary") "Deployment mode should be binary"

        print "✅ Service definition retrieval works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Failed to get service definition"
        false
    }
}

# Test dependency resolution
export def test-dependency-resolution [] {
    print "Testing: Dependency resolution"

    # Resolve and validate dependencies (no try-catch)
    let result = (do {
        let deps = (resolve-dependencies "control-center")

        assert ("orchestrator" in $deps) "Should resolve orchestrator dependency"

        print "✅ Dependency resolution works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Dependency resolution failed"
        false
    }
}

# Test dependency graph validation
export def test-dependency-graph [] {
    print "Testing: Dependency graph validation"

    # Validate dependency graph (no try-catch)
    let result = (do {
        let validation = (validate-dependency-graph)

        assert ($validation.valid) "Dependency graph should be valid"
        assert (not $validation.has_cycles) "Should not have cycles"

        print "✅ Dependency graph is valid"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Dependency graph validation failed"
        false
    }
}

# Test startup order calculation
export def test-startup-order [] {
    print "Testing: Startup order calculation"

    # Calculate and validate startup order (no try-catch)
    let result = (do {
        let services = ["control-center", "orchestrator"]
        let order = (get-startup-order $services)

        let orchestrator_idx = ($order | enumerate | where item == "orchestrator" | get index | get 0)
        let control_center_idx = ($order | enumerate | where item == "control-center" | get index | get 0)

        assert ($orchestrator_idx < $control_center_idx) "Orchestrator should start before control-center"

        print "✅ Startup order calculation works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Startup order calculation failed"
        false
    }
}

# Test service prerequisites validation
export def test-prerequisites-validation [] {
    print "Testing: Prerequisites validation"

    # Validate prerequisites (no try-catch)
    let result = (do {
        let validation = (validate-service-prerequisites "orchestrator")

        assert ("valid" in $validation) "Validation should have valid field"
        assert ("can_start" in $validation) "Validation should have can_start field"

        print "✅ Prerequisites validation works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Prerequisites validation failed"
        false
    }
}

# Test conflict detection
export def test-conflict-detection [] {
    print "Testing: Conflict detection"

    # Check for service conflicts (no try-catch)
    let result = (do {
        let conflicts = (check-service-conflicts "coredns")

        assert ("has_conflicts" in $conflicts) "Should have has_conflicts field"

        print "✅ Conflict detection works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Conflict detection failed"
        false
    }
}

# Test required services check
export def test-required-services-check [] {
    print "Testing: Required services check"

    # Check required services (no try-catch)
    let result = (do {
        let check = (check-required-services "server")

        assert ("required_services" in $check) "Should have required_services field"
        assert ("all_running" in $check) "Should have all_running field"
        assert ("can_auto_start" in $check) "Should have can_auto_start field"

        assert ("orchestrator" in $check.required_services) "Orchestrator should be required for server ops"

        print "✅ Required services check works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Required services check failed"
        false
    }
}

# Test all services validation
export def test-all-services-validation [] {
    print "Testing: All services validation"

    # Validate all services (no try-catch)
    let result = (do {
        let validation = (validate-all-services)

        assert ($validation.total_services > 0) "Should have services"
        assert ("valid_services" in $validation) "Should have valid_services count"

        print "✅ All services validation works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ All services validation failed"
        false
    }
}

# Test readiness report
export def test-readiness-report [] {
    print "Testing: Readiness report"

    # Get and validate readiness report (no try-catch)
    let result = (do {
        let report = (get-readiness-report)

        assert ($report.total_services > 0) "Should have services"
        assert ("running_services" in $report) "Should have running count"
        assert ("services" in $report) "Should have services list"

        print "✅ Readiness report works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Readiness report failed"
        false
    }
}

# Test dependency tree
export def test-dependency-tree [] {
    print "Testing: Dependency tree generation"

    # Generate and validate dependency tree (no try-catch)
    let result = (do {
        let tree = (get-dependency-tree "control-center")

        assert ($tree.service == "control-center") "Root should be control-center"
        assert ("dependencies" in $tree) "Should have dependencies field"

        print "✅ Dependency tree generation works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Dependency tree generation failed"
        false
    }
}

# Test reverse dependencies
export def test-reverse-dependencies [] {
    print "Testing: Reverse dependencies"

    # Get and validate reverse dependencies (no try-catch)
    let result = (do {
        let reverse_deps = (get-reverse-dependencies "orchestrator")

        assert ("control-center" in $reverse_deps) "Control-center should depend on orchestrator"

        print "✅ Reverse dependencies work"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Reverse dependencies failed"
        false
    }
}

# Test can-stop-service
export def test-can-stop-service [] {
    print "Testing: Can-stop-service check"

    # Check if service can be stopped (no try-catch)
    let result = (do {
        let can_stop = (can-stop-service "orchestrator")

        assert ("can_stop" in $can_stop) "Should have can_stop field"
        assert ("dependent_services" in $can_stop) "Should have dependent_services field"

        print "✅ Can-stop-service check works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Can-stop-service check failed"
        false
    }
}

# Test service state initialization
export def test-service-state-init [] {
    print "Testing: Service state initialization"

    # Initialize and validate service state (no try-catch)
    let result = (do {
        init-service-state

        let state_dir = $"($env.HOME)/.provisioning/services/state"
        let pid_dir = $"($env.HOME)/.provisioning/services/pids"
        let log_dir = $"($env.HOME)/.provisioning/services/logs"

        assert ($state_dir | path exists) "State directory should exist"
        assert ($pid_dir | path exists) "PID directory should exist"
        assert ($log_dir | path exists) "Log directory should exist"

        print "✅ Service state initialization works"
        true
    } | complete)

    if $result.exit_code == 0 {
        $result.stdout
    } else {
        print "❌ Service state initialization failed"
        false
    }
}

# Run all tests
export def main [] {
    print "=== Service Management System Tests ===\n"

    let tests = [
        test-service-registry-loading
        test-service-definition
        test-dependency-resolution
        test-dependency-graph
        test-startup-order
        test-prerequisites-validation
        test-conflict-detection
        test-required-services-check
        test-all-services-validation
        test-readiness-report
        test-dependency-tree
        test-reverse-dependencies
        test-can-stop-service
        test-service-state-init
    ]

    mut passed = 0
    mut failed = 0

    for test in $tests {
        # Run test with error handling (no try-catch)
        let result = (do { do $test } | complete)
        if $result.exit_code == 0 {
            if ($result.stdout) {
                $passed = $passed + 1
            } else {
                $failed = $failed + 1
            }
        } else {
            print $"❌ Test ($test) threw an error"
            $failed = $failed + 1
        }

        print ""
    }

    print $"=== Test Results ==="
    print $"Passed: ($passed)"
    print $"Failed: ($failed)"
    print $"Total:  (($tests | length))"

    if $failed == 0 {
        print "\n✅ All tests passed!"
    } else {
        print $"\n❌ ($failed) tests failed"
    }
}
