#!/usr/bin/env nu

# Provider Management CLI
# Manages cloud providers for infrastructures with KCL integration
# Author: JesusPerezLorenzo
# Date: 2025-09-29

use ../nulib/lib_provisioning/kcl_module_loader.nu *

# Main providers command
def main [] {
    print_help
}

# List all available providers
export def "main list" [
    --kcl                     # Show KCL module information (always enabled)
    --format: string = "table" # Output format: table, json, yaml
] {
    # Always use KCL module loader
    let providers = (discover-kcl-modules "providers")

    match $format {
        "json" => ($providers | to json)
        "yaml" => ($providers | to yaml)
        _ => ($providers | table)
    }
}

# Show detailed information about a provider
export def "main info" [
    provider: string          # Provider name
    --kcl                     # Show KCL schema information
] {
    print $"📋 Provider Information: ($provider)"
    print ""

    let providers = (discover-kcl-modules "providers")
    let provider_info = ($providers | where name == $provider)

    if ($provider_info | is-empty) {
        print $"❌ Provider not found: ($provider)"
        return
    }

    let info = ($provider_info | first)

    print $"  Name: ($info.name)"
    print $"  Type: ($info.type)"
    print $"  Path: ($info.path)"
    print $"  Has KCL: ($info.has_kcl)"

    if $kcl and $info.has_kcl {
        print ""
        print "  KCL Module:"
        print $"    Module Name: ($info.kcl_module_name)"
        print $"    KCL Path: ($info.kcl_path)"
        print $"    Version: ($info.version)"
        print $"    Edition: ($info.edition)"

        # Check for kcl.mod file
        let kcl_mod = ($info.kcl_path | path join "kcl.mod")
        if ($kcl_mod | path exists) {
            print ""
            print $"  kcl.mod content:"
            open $kcl_mod | lines | each {|line| print $"    ($line)"}
        }
    }
}

# Install a provider for an infrastructure
export def "main install" [
    provider: string,         # Provider name (e.g., upcloud, aws, local)
    infra: string,            # Infrastructure name or path
    --version: string = "0.0.1", # Provider version
    --manifest: string = "providers.manifest.yaml" # Manifest file name
] {
    # Resolve infrastructure path
    let infra_path = resolve-infra-path $infra

    if ($infra_path | is-empty) {
        print $"❌ Infrastructure not found: ($infra)"
        return
    }

    # Use library function to install provider
    install-provider $provider $infra_path --version $version

    print ""
    print $"💡 Next steps:"
    print $"  1. Check the manifest: ($infra_path)/($manifest)"
    print $"  2. Update server definitions to use ($provider)"
    print $"  3. Run: kcl run defs/servers.k"
}

# Remove a provider from an infrastructure
export def "main remove" [
    provider: string,         # Provider name
    infra: string,            # Infrastructure name or path
    --force                   # Force removal without confirmation
] {
    # Resolve infrastructure path
    let infra_path = resolve-infra-path $infra

    if ($infra_path | is-empty) {
        print $"❌ Infrastructure not found: ($infra)"
        return
    }

    # Confirmation unless forced
    if not $force {
        print $"⚠️  This will remove provider ($provider) from ($infra)"
        print "   KCL dependencies will be updated."
        let response = (input "Continue? (y/N): ")

        if ($response | str downcase) != "y" {
            print "❌ Cancelled"
            return
        }
    }

    # Use library function to remove provider
    remove-provider $provider $infra_path
}

# List installed providers for an infrastructure
export def "main installed" [
    infra: string,            # Infrastructure name or path
    --format: string = "table" # Output format
] {
    # Resolve infrastructure path
    let infra_path = resolve-infra-path $infra

    if ($infra_path | is-empty) {
        print $"❌ Infrastructure not found: ($infra)"
        return
    }

    let manifest_path = ($infra_path | path join "providers.manifest.yaml")

    if not ($manifest_path | path exists) {
        print $"❌ No providers.manifest.yaml found in ($infra)"
        return
    }

    let manifest = (open $manifest_path)
    let providers = if ($manifest | get providers? | is-not-empty) {
        $manifest | get providers
    } else if ($manifest | get loaded_providers? | is-not-empty) {
        $manifest | get loaded_providers
    } else {
        []
    }

    print $"📦 Installed providers for ($infra):"
    print ""

    match $format {
        "json" => ($providers | to json)
        "yaml" => ($providers | to yaml)
        _ => ($providers | table)
    }
}

# Validate provider installation for an infrastructure
export def "main validate" [
    infra: string             # Infrastructure name or path
] {
    print $"🔍 Validating providers for ($infra)..."
    print ""

    # Resolve infrastructure path
    let infra_path = resolve-infra-path $infra

    if ($infra_path | is-empty) {
        print $"❌ Infrastructure not found: ($infra)"
        return
    }

    mut validation_errors = []

    # Check manifest exists
    let manifest_path = ($infra_path | path join "providers.manifest.yaml")
    if not ($manifest_path | path exists) {
        $validation_errors = ($validation_errors | append "providers.manifest.yaml not found")
    } else {
        # Check each provider in manifest
        let manifest = (open $manifest_path)
        let providers = ($manifest | get providers)

        for provider in $providers {
            print $"  Checking ($provider.name)..."

            # Check if provider exists
            let available = (discover-kcl-modules "providers" | where name == $provider.name)

            if ($available | is-empty) {
                $validation_errors = ($validation_errors | append $"Provider not found: ($provider.name)")
                print $"    ❌ Not found in extensions"
            } else {
                let provider_info = ($available | first)

                # Check if symlink exists
                let modules_dir = ($infra_path | path join ".kcl-modules")
                let link_path = ($modules_dir | path join $provider_info.kcl_module_name)

                if not ($link_path | path exists) {
                    $validation_errors = ($validation_errors | append $"Symlink missing: ($link_path)")
                    print $"    ❌ Symlink not found"
                } else {
                    print $"    ✓ OK"
                }
            }
        }
    }

    # Check kcl.mod
    let kcl_mod_path = ($infra_path | path join "kcl.mod")
    if not ($kcl_mod_path | path exists) {
        $validation_errors = ($validation_errors | append "kcl.mod not found")
    }

    print ""

    # Report results
    if ($validation_errors | is-empty) {
        print "✅ Validation passed - all providers correctly installed"
        return true
    } else {
        print "❌ Validation failed:"
        for error in $validation_errors {
            print $"  • ($error)"
        }
        return false
    }
}

# Helper: Resolve infrastructure path
def resolve-infra-path [infra: string]: nothing -> string {
    if ($infra | path exists) {
        return $infra
    }

    # Try workspace/infra path
    let workspace_path = $"workspace/infra/($infra)"
    if ($workspace_path | path exists) {
        return $workspace_path
    }

    # Try absolute workspace path
    let abs_workspace_path = $"/Users/Akasha/project-provisioning/workspace/infra/($infra)"
    if ($abs_workspace_path | path exists) {
        return $abs_workspace_path
    }

    return ""
}

# Helper: Print help
def print_help [] {
    print "Provider Management CLI"
    print ""
    print "Usage: providers <command> [options]"
    print ""
    print "COMMANDS:"
    print "  list [--kcl] [--format <fmt>]              - List all available providers"
    print "  info <provider> [--kcl]                    - Show detailed provider information"
    print "  install <provider> <infra> [--version <v>] - Install provider for infrastructure"
    print "  remove <provider> <infra> [--force]        - Remove provider from infrastructure"
    print "  installed <infra> [--format <fmt>]         - List installed providers"
    print "  validate <infra>                           - Validate provider installation"
    print ""
    print "OPTIONS:"
    print "  --kcl           Show KCL module information"
    print "  --format <fmt>  Output format: table, json, yaml"
    print "  --force         Skip confirmation prompts"
    print "  --version <v>   Specify provider version (default: 0.0.1)"
    print ""
    print "EXAMPLES:"
    print "  providers list --kcl"
    print "  providers info upcloud --kcl"
    print "  providers install upcloud wuji"
    print "  providers installed wuji"
    print "  providers validate wuji"
    print "  providers remove aws wuji --force"
    print ""
    print "See also: module-loader sync-kcl"
}