# Test Script for OCI Implementation
# Validates the multi-repo architecture with OCI registry support
# Version: 1.0.0

use std log

# Test 1: Check if OCI tools are available
export def "test oci-tools" []: nothing -> bool {
    log info "Test 1: Checking OCI tools availability..."

    let tools = ["oras" "crane" "skopeo"]
    mut found = false

    for tool in $tools {
        if (which $tool | is-not-empty) {
            log info $"  ✓ Found ($tool)"
            $found = true
            break
        }
    }

    if not $found {
        log warning "  ⚠ No OCI tools found (install oras, crane, or skopeo)"
        log warning "    Installation: brew install oras"
    }

    $found
}

# Test 2: Validate KCL schemas
export def "test kcl-schemas" []: nothing -> bool {
    log info "Test 2: Validating KCL schemas..."

    let result = (do {
        cd provisioning/kcl
        kcl run dependencies.k
    } | complete)

    if $result.exit_code != 0 {
        log error $"  ✗ KCL schema compilation failed: ($result.stderr)"
        false
    } else {
        log info "  ✓ KCL schemas compile successfully"
        true
    }
}

# Test 3: Check Nushell module syntax
export def "test nushell-modules" []: nothing -> bool {
    log info "Test 3: Checking Nushell module syntax..."

    let modules = [
        "provisioning/core/nulib/lib_provisioning/oci/client.nu"
        "provisioning/core/nulib/lib_provisioning/oci/commands.nu"
        "provisioning/core/nulib/lib_provisioning/dependencies/resolver.nu"
        "provisioning/tools/oci-package.nu"
        "provisioning/tools/migrate-to-oci.nu"
    ]

    let results = $modules | each {|module|
        let basename = ($module | path basename)
        let result = (do {
            nu --commands $"use ($module)"
        } | complete)

        if $result.exit_code != 0 {
            log error $"  ✗ ($basename) - Syntax error"
            false
        } else {
            log info $"  ✓ ($basename) - Valid syntax"
            true
        }
    }

    $results | all {|it| $it == true}
}

# Test 4: Validate directory structure
export def "test directory-structure" []: nothing -> bool {
    log info "Test 4: Validating directory structure..."

    let required_dirs = [
        "provisioning/core/nulib/lib_provisioning/oci"
        "provisioning/core/nulib/lib_provisioning/dependencies"
        "provisioning/tools"
        "docs/architecture"
        "docs/user"
    ]

    mut all_exist = true

    for dir in $required_dirs {
        if ($dir | path exists) {
            log info $"  ✓ ($dir) exists"
        } else {
            log error $"  ✗ ($dir) missing"
            $all_exist = false
        }
    }

    $all_exist
}

# Test 5: Validate documentation
export def "test documentation" []: nothing -> bool {
    log info "Test 5: Validating documentation..."

    let required_docs = [
        "docs/architecture/MULTI_REPO_ARCHITECTURE.md"
        "docs/user/OCI_REGISTRY_GUIDE.md"
        "docs/QUICK_REFERENCE_OCI.md"
        "MULTI_REPO_OCI_IMPLEMENTATION_SUMMARY.md"
    ]

    mut all_exist = true

    for doc in $required_docs {
        if ($doc | path exists) {
            let doc_name = ($doc | path basename)
            let size = (ls $doc | first | get size)
            let size_info = $"($size) bytes"
            log info $"  ✓ ($doc_name) exists ($size_info)"
        } else {
            log error $"  ✗ ($doc | path basename) missing"
            $all_exist = false
        }
    }

    $all_exist
}

# Test 6: Count implementation lines
export def "test implementation-size" []: nothing -> bool {
    log info "Test 6: Counting implementation lines..."

    let files = [
        "provisioning/kcl/dependencies.k"
        "provisioning/core/nulib/lib_provisioning/oci/client.nu"
        "provisioning/core/nulib/lib_provisioning/oci/commands.nu"
        "provisioning/core/nulib/lib_provisioning/dependencies/resolver.nu"
        "provisioning/tools/oci-package.nu"
        "provisioning/tools/migrate-to-oci.nu"
    ]

    mut total_lines = 0

    for file in $files {
        if ($file | path exists) {
            let lines = (open $file | lines | length)
            $total_lines = ($total_lines + $lines)
            log info $"  - ($file | path basename): ($lines) lines"
        }
    }

    log info $"  ✓ Total implementation: ($total_lines) lines"

    ($total_lines > 2000)  # Should have at least 2000 lines
}

# Test 7: Validate manifest template
export def "test manifest-template" []: nothing -> bool {
    log info "Test 7: Testing manifest generation..."

    let result = (do {
        let package_file = "provisioning/tools/oci-package.nu"
        if ($package_file | path exists) {
            "available"
        } else {
            error make {msg: "OCI package tool missing"}
        }
    } | complete)

    if $result.exit_code != 0 {
        log error $"  ✗ Manifest template test failed: ($result.stderr)"
        false
    } else {
        log info "  ✓ OCI package tool available"
        true
    }
}

# Run all tests
export def main []: nothing -> record {
    log info "="
    log info "OCI Implementation Test Suite"
    log info "="
    log info ""

    mut results = {
        oci_tools: (test oci-tools)
        kcl_schemas: (test kcl-schemas)
        nushell_modules: (test nushell-modules)
        directory_structure: (test directory-structure)
        documentation: (test documentation)
        implementation_size: (test implementation-size)
        manifest_template: (test manifest-template)
    }

    log info ""
    log info "="
    log info "Test Summary"
    log info "="

    let total = ($results | values | length)
    let passed = ($results | values | where $it == true | length)
    let failed = ($total - $passed)

    log info $"Total tests: ($total)"
    log info $"Passed: ($passed)"
    log info $"Failed: ($failed)"
    log info ""

    # Show failed tests
    if $failed > 0 {
        log warning "Failed tests:"
        for test in ($results | transpose key value) {
            if not $test.value {
                log warning $"  - ($test.key)"
            }
        }
    }

    if $failed == 0 {
        log info "✓ All tests passed!"
    } else {
        log warning $"⚠ ($failed) test(s) failed"
    }

    $results
}
