#!/usr/bin/env nu
# Test Suite for Workspace Enforcement and Version Tracking
# Validates workspace requirement enforcement and migration framework

use std assert

# Test workspace version comparison
export def test_version_comparison [] {
    use ../lib_provisioning/workspace/version.nu *

    print "Testing version comparison..."

    # Test equal versions
    assert equal (compare-versions "2.0.5" "2.0.5") "equal"

    # Test greater versions
    assert equal (compare-versions "2.1.0" "2.0.5") "greater"
    assert equal (compare-versions "3.0.0" "2.0.5") "greater"
    assert equal (compare-versions "2.0.6" "2.0.5") "greater"

    # Test lesser versions
    assert equal (compare-versions "2.0.4" "2.0.5") "less"
    assert equal (compare-versions "1.9.9" "2.0.5") "less"
    assert equal (compare-versions "2.0.0" "2.0.5") "less"

    print "✓ Version comparison tests passed"
}

# Test version compatibility checking
export def test_version_compatibility [] {
    use ../lib_provisioning/workspace/version.nu *

    print "Testing version compatibility..."

    # Compatible versions
    assert (is-version-compatible "2.0.5" "2.0.0")
    assert (is-version-compatible "2.1.0" "2.0.5")
    assert (is-version-compatible "2.0.5" "2.0.5")

    # Incompatible versions
    assert not (is-version-compatible "2.0.0" "2.0.5")
    assert not (is-version-compatible "1.9.9" "2.0.0")

    print "✓ Version compatibility tests passed"
}

# Test workspace metadata initialization
export def test_metadata_initialization [] {
    use ../lib_provisioning/workspace/version.nu *

    print "Testing metadata initialization..."

    # Create temporary test workspace
    let test_workspace = ("/tmp/test_workspace_" + (random chars --length 8))
    mkdir $test_workspace

    # Initialize and validate metadata (no try-catch)
    let result = (do {
        let metadata = (init-workspace-metadata $test_workspace "test_workspace")

        assert ($metadata.workspace.name == "test_workspace")
        assert ($metadata.workspace.path == $test_workspace)
        assert ("provisioning" in $metadata.version)
        assert ("schema" in $metadata.version)
        assert ("workspace_format" in $metadata.version)
        assert ("created" in $metadata)
        assert ("migration_history" in $metadata)

        let metadata_path = (get-workspace-metadata-path $test_workspace)
        assert ($metadata_path | path exists)

        print "✓ Metadata initialization tests passed"
    } | complete)

    # Cleanup
    rm -rf $test_workspace
}

# Test workspace structure validation
export def test_structure_validation [] {
    use ../lib_provisioning/workspace/version.nu *

    print "Testing workspace structure validation..."

    # Create test workspace with valid structure
    let test_workspace = ("/tmp/test_workspace_" + (random chars --length 8))
    mkdir $test_workspace
    mkdir ($test_workspace | path join "config")
    mkdir ($test_workspace | path join "infra")
    mkdir ($test_workspace | path join ".provisioning")

    # Create required config file
    "" | save -f ($test_workspace | path join "config" | path join "provisioning.yaml")

    # Validate valid workspace structure (no try-catch)
    let result1 = (do {
        let validation = (validate-workspace-structure $test_workspace)

        assert $validation.valid
        assert (($validation.errors) == 0)

        print "✓ Structure validation tests passed (valid workspace)"
    } | complete)

    # Cleanup
    rm -rf $test_workspace

    # Test invalid workspace
    let invalid_workspace = ("/tmp/test_workspace_invalid_" + (random chars --length 8))
    mkdir $invalid_workspace

    # Validate invalid workspace structure (no try-catch)
    let result2 = (do {
        let validation = (validate-workspace-structure $invalid_workspace)

        assert (not $validation.valid)
        assert (($validation.errors) > 0)

        print "✓ Structure validation tests passed (invalid workspace)"
    } | complete)

    # Cleanup
    rm -rf $invalid_workspace
}

# Test workspace enforcement - exempt commands
export def test_enforcement_exempt_commands [] {
    use ../lib_provisioning/workspace/enforcement.nu *

    print "Testing workspace enforcement - exempt commands..."

    # Exempt commands should not require workspace
    assert not (command-requires-workspace "help")
    assert not (command-requires-workspace "version")
    assert not (command-requires-workspace "workspace")
    assert not (command-requires-workspace "guide")
    assert not (command-requires-workspace "nu")

    # Non-exempt commands should require workspace
    assert (command-requires-workspace "server")
    assert (command-requires-workspace "taskserv")
    assert (command-requires-workspace "cluster")
    assert (command-requires-workspace "infra")

    print "✓ Enforcement exempt commands tests passed"
}

# Test migration path finding
export def test_migration_path_finding [] {
    use ../lib_provisioning/workspace/migration.nu *

    print "Testing migration path finding..."

    # Test unknown to 2.0.5 migration
    let path = (find-migration-path "unknown" "2.0.5")
    assert (($path | length) > 0)
    assert (($path | first).strategy == "unknown_to_2.0.5")

    # Test 2.0.0 to 2.0.5 migration
    let path2 = (find-migration-path "2.0.0" "2.0.5")
    assert (($path2 | length) > 0)

    # Test same version (no migration needed)
    let path3 = (find-migration-path "2.0.5" "2.0.5")
    assert (($path3 | is-empty))

    print "✓ Migration path finding tests passed"
}

# Test workspace backup creation
export def test_backup_creation [] {
    use ../lib_provisioning/workspace/migration.nu *

    print "Testing workspace backup creation..."

    # Create test workspace
    let test_workspace = ("/tmp/test_workspace_backup_" + (random chars --length 8))
    mkdir $test_workspace
    mkdir ($test_workspace | path join "config")
    "test content" | save -f ($test_workspace | path join "config" | path join "test.yaml")

    # Create and validate backup (no try-catch)
    let result = (do {
        let backup_result = (create-workspace-backup $test_workspace "test_backup")

        assert $backup_result.success
        assert ($backup_result.backup_path | path exists)

        let backup_config = ($backup_result.backup_path | path join "config" | path join "test.yaml")
        assert ($backup_config | path exists)

        let backup_info = ($backup_result.backup_path | path join ".backup_info.yaml")
        assert ($backup_info | path exists)

        print "✓ Backup creation tests passed"

        rm -rf ($backup_result.backup_path | path dirname)
    } | complete)

    # Cleanup workspace
    rm -rf $test_workspace
}

# Test compatibility checking with different scenarios
export def test_compatibility_scenarios [] {
    use ../lib_provisioning/workspace/version.nu *

    print "Testing compatibility scenarios..."

    # Scenario 1: No metadata (requires migration)
    let test_workspace1 = ("/tmp/test_ws_compat1_" + (random chars --length 8))
    mkdir $test_workspace1

    # Check compatibility without metadata (no try-catch)
    let result1 = (do {
        let compat1 = (check-workspace-compatibility $test_workspace1)

        assert (not $compat1.compatible)
        assert ($compat1.reason == "no_metadata")
        assert $compat1.requires_migration

        print "✓ Compatibility test 1 passed (no metadata)"
    } | complete)

    rm -rf $test_workspace1

    # Scenario 2: Valid metadata matching system version
    let test_workspace2 = ("/tmp/test_ws_compat2_" + (random chars --length 8))
    mkdir $test_workspace2

    # Check compatibility with metadata (no try-catch)
    let result2 = (do {
        init-workspace-metadata $test_workspace2 "test_workspace"

        let compat2 = (check-workspace-compatibility $test_workspace2)

        assert $compat2.compatible
        assert ($compat2.reason == "version_match" or $compat2.reason == "migration_available")

        print "✓ Compatibility test 2 passed (valid metadata)"
    } | complete)

    rm -rf $test_workspace2
}

# Run all tests
export def main [] {
    print ""
    print "=========================================="
    print "Workspace Enforcement & Migration Tests"
    print "=========================================="
    print ""

    let result = (do {
        test_version_comparison
        test_version_compatibility
        test_metadata_initialization
        test_structure_validation
        test_enforcement_exempt_commands
        test_migration_path_finding
        test_backup_creation
        test_compatibility_scenarios
    } | complete)

    if $result.exit_code == 0 {
        print ""
        print "=========================================="
        print "✓ All tests passed successfully!"
        print "=========================================="
        print ""
    } else {
        print ""
        print "=========================================="
        print $"✗ Test failed: ($result.stderr)"
        print "=========================================="
        print ""
        exit 1
    }
}
