#!/usr/bin/env nu
# Register provisioning critical plugins with Nushell
#
# This script registers the three critical provisioning plugins:
# - nu_plugin_auth: JWT authentication with system keyring
# - nu_plugin_kms: Multi-backend KMS encryption
# - nu_plugin_orchestrator: Local orchestrator operations
#
# Usage:
#   nu scripts/register-provisioning-plugins.nu
#   nu scripts/register-provisioning-plugins.nu --verify
#   nu scripts/register-provisioning-plugins.nu --force

use std log

# Plugin metadata
const PROVISIONING_PLUGINS = [
    {
        name: "nu_plugin_auth"
        description: "JWT authentication with system keyring"
        commands: ["auth login", "auth logout", "auth verify", "auth sessions", "auth mfa enroll", "auth mfa verify"]
        priority: 1
    }
    {
        name: "nu_plugin_kms"
        description: "Multi-backend KMS encryption (RustyVault, Age, AWS, Vault, Cosmian)"
        commands: ["kms encrypt", "kms decrypt", "kms generate-key", "kms status", "kms list-backends"]
        priority: 2
    }
    {
        name: "nu_plugin_orchestrator"
        description: "Local orchestrator operations (10-30x faster than HTTP)"
        commands: ["orch status", "orch tasks", "orch validate", "orch submit", "orch monitor"]
        priority: 3
    }
]

# Get plugin binary path for the current platform
def get-plugin-path [plugin_name: string, base_dir: path]: nothing -> path {
    let release_path = ($base_dir | path join $plugin_name "target" "release" $plugin_name)
    let debug_path = ($base_dir | path join $plugin_name "target" "debug" $plugin_name)

    # Prefer release build
    if ($release_path | path exists) {
        return $release_path
    }

    # Fall back to debug build
    if ($debug_path | path exists) {
        return $debug_path
    }

    # Not found
    return ""
}

# Check if plugin is already registered
def is-plugin-registered [plugin_name: string]: nothing -> bool {
    let registered = (plugin list | where name == $plugin_name)
    ($registered | length) > 0
}

# Register a single plugin
def register-plugin [
    plugin_name: string
    plugin_path: path
    --force: bool = false
]: nothing -> record {
    let start_time = (date now)

    # Check if already registered
    if (not $force) and (is-plugin-registered $plugin_name) {
        return {
            name: $plugin_name
            status: "already_registered"
            message: "Plugin already registered (use --force to re-register)"
            duration_ms: 0
        }
    }

    # Check if plugin binary exists
    if ($plugin_path | is-empty) or (not ($plugin_path | path exists)) {
        return {
            name: $plugin_name
            status: "not_found"
            message: $"Plugin binary not found at expected location"
            duration_ms: 0
        }
    }

    # Register the plugin
    try {
        plugin add $plugin_path
        let duration = ((date now) - $start_time) | into int | $in / 1_000_000

        return {
            name: $plugin_name
            status: "registered"
            message: "Plugin registered successfully"
            path: $plugin_path
            duration_ms: $duration
        }
    } catch { |err|
        let duration = ((date now) - $start_time) | into int | $in / 1_000_000

        return {
            name: $plugin_name
            status: "error"
            message: $"Failed to register: ($err.msg)"
            duration_ms: $duration
        }
    }
}

# Verify plugin registration by checking commands
def verify-plugin-registration [plugin_name: string]: nothing -> record {
    let plugin_info = (PROVISIONING_PLUGINS | where name == $plugin_name | first)

    if ($plugin_info == null) {
        return {
            name: $plugin_name
            verified: false
            message: "Unknown plugin"
        }
    }

    # Check if plugin is in plugin list
    let registered = (plugin list | where name == $plugin_name)

    if ($registered | length) == 0 {
        return {
            name: $plugin_name
            verified: false
            message: "Plugin not found in registry"
        }
    }

    return {
        name: $plugin_name
        verified: true
        description: $plugin_info.description
        commands: $plugin_info.commands
        message: "Plugin verified successfully"
    }
}

# Main entry point
def main [
    --force (-f)    # Force re-registration even if already registered
    --verify (-v)   # Verify registration after completion
    --quiet (-q)    # Suppress output
]: nothing -> nothing {
    let base_dir = ($env.PWD | path dirname | path dirname | path dirname | path join "plugins" "nushell-plugins")

    # Fallback: try current directory if we're already in nushell-plugins
    let base_dir = if ($base_dir | path join "nu_plugin_auth" | path exists) {
        $base_dir
    } else if (($env.PWD | path join "nu_plugin_auth") | path exists) {
        $env.PWD
    } else {
        # Try to find from script location
        let script_dir = ($env.CURRENT_FILE? | default $env.PWD | path dirname)
        let parent = ($script_dir | path dirname)
        if ($parent | path join "nu_plugin_auth" | path exists) {
            $parent
        } else {
            $env.PWD
        }
    }

    if not $quiet {
        print ""
        print "======================================================"
        print "   Provisioning Plugins Registration"
        print "======================================================"
        print ""
        print $"Base directory: ($base_dir)"
        print ""
    }

    mut results = []
    mut registered_count = 0
    mut failed_count = 0

    # Register each plugin
    for plugin_info in $PROVISIONING_PLUGINS {
        let plugin_name = $plugin_info.name
        let plugin_path = (get-plugin-path $plugin_name $base_dir)

        if not $quiet {
            print $"Registering ($plugin_name)..."
        }

        let result = (register-plugin $plugin_name $plugin_path --force=$force)
        $results = ($results | append $result)

        match $result.status {
            "registered" | "already_registered" => {
                $registered_count = ($registered_count + 1)
                if not $quiet {
                    if $result.status == "registered" {
                        print $"  [OK] ($result.message) \(($result.duration_ms)ms\)"
                    } else {
                        print $"  [SKIP] ($result.message)"
                    }
                }
            }
            "not_found" => {
                $failed_count = ($failed_count + 1)
                if not $quiet {
                    print $"  [WARN] ($result.message)"
                    print $"         Expected at: ($base_dir)/($plugin_name)/target/release/($plugin_name)"
                }
            }
            "error" => {
                $failed_count = ($failed_count + 1)
                if not $quiet {
                    print $"  [ERROR] ($result.message)"
                }
            }
            _ => {
                $failed_count = ($failed_count + 1)
            }
        }
    }

    if not $quiet {
        print ""
        print "------------------------------------------------------"
        print $"Summary: ($registered_count) registered, ($failed_count) failed"
        print "------------------------------------------------------"
    }

    # Verify if requested
    if $verify {
        if not $quiet {
            print ""
            print "Verifying plugin registration..."
            print ""
        }

        for plugin_info in $PROVISIONING_PLUGINS {
            let verification = (verify-plugin-registration $plugin_info.name)

            if not $quiet {
                if $verification.verified {
                    print $"[OK] ($verification.name): ($verification.description)"
                    print $"     Commands: ($verification.commands | str join ', ')"
                } else {
                    print $"[FAIL] ($verification.name): ($verification.message)"
                }
            }
        }
    }

    if not $quiet {
        print ""
        print "Plugin commands available:"
        print "  - auth login/logout/verify/sessions/mfa"
        print "  - kms encrypt/decrypt/generate-key/status/list-backends"
        print "  - orch status/tasks/validate/submit/monitor"
        print ""
        print "Verify with: plugin list"
        print ""
    }
}

# Export for use as module
export def "provisioning-plugins register" [--force (-f), --verify (-v), --quiet (-q)] {
    main --force=$force --verify=$verify --quiet=$quiet
}

export def "provisioning-plugins list" [] {
    PROVISIONING_PLUGINS
}

export def "provisioning-plugins status" [] {
    mut status_list = []

    for plugin_info in $PROVISIONING_PLUGINS {
        let registered = (is-plugin-registered $plugin_info.name)
        $status_list = ($status_list | append {
            name: $plugin_info.name
            registered: $registered
            description: $plugin_info.description
            commands: ($plugin_info.commands | length)
        })
    }

    $status_list
}
