# Module: Plugins Module Exports
# Purpose: Central export point for all plugin system components (auth, kms, etc.).
# Dependencies: auth, kms, and other plugin modules

# Plugin Wrapper Modules
# Exports all plugin wrappers with HTTP fallback support

# plugins/ subsystem facade — selective re-exports (ADR-025 Phase 3 Layer 3).

export use auth.nu [plugin-auth-status]
export use kms.nu [
    plugin-kms-backends plugin-kms-decrypt plugin-kms-encrypt
    plugin-kms-generate-key plugin-kms-info plugin-kms-list-keys
    plugin-kms-rotate-key plugin-kms-status
]
export use secretumvault.nu [
    decrypt-config-file encrypt-config-file plugin-secretumvault-decrypt
    plugin-secretumvault-encrypt plugin-secretumvault-generate-key
    plugin-secretumvault-health plugin-secretumvault-info
    plugin-secretumvault-rotate-key plugin-secretumvault-version
]

# config/accessor star-import was dead (no accessor symbols used in body) —
# dropped. Add _ansi explicitly — previously came through an implicit chain.
use lib_provisioning/utils/interface.nu [_ansi]

# List all available plugins with status
export def list-plugins [] {
    let installed_str = (version).installed_plugins
    let installed_list = ($installed_str | split row ", ")

    # Parse installed plugins to extract name and version
    let parsed_plugins = ($installed_list | each {|p|
        let parts = ($p | split row " ")
        let name = ($parts | get 0)
        let version = if ($parts | length) > 1 {
            ($parts | get 1)
        } else {
            "unknown"
        }
        {name: $name, version: $version}
    })

    # Build table with all plugins sorted by name
    $parsed_plugins
    | sort-by name
    | each {|plugin|
        let is_core = (
            ($plugin.name | str contains "auth") or
            ($plugin.name | str contains "kms") or
            ($plugin.name | str contains "orchestrator") or
            ($plugin.name | str contains "secretumvault") or
            ($plugin.name | str contains "tera") or
            ($plugin.name | str contains "nickel")
        )
        let status = if $is_core { "enabled" } else { "active" }

        let description = match $plugin.name {
            "auth" => "JWT authentication with MFA support"
            "kms" => "Key Management Service integration"
            "secretumvault" => "SecretumVault KMS integration"
            "tera" => "Template rendering engine"
            "nickel" => "Nickel configuration language"
            "clipboard" => "Clipboard operations"
            "desktop_notifications" => "Desktop notifications"
            "qr_maker" => "QR code generation"
            "port_extension" => "Port scanning utility"
            "orchestrator" => "Workflow orchestration engine"
            "polars" => "Data frame operations"
            "query" => "Query builder operations"
            "formats" => "Data format conversions"
            "image" => "Image processing operations"
            "hashes" => "Hash algorithms"
            "highlight" => "Syntax highlighting"
            "stress_internals" => "Internal performance testing"
            "gstat" => "Git status integration"
            "custom_values" => "Custom value types"
            "example" => "Example plugin"
            "fluent" => "Fluent API helpers"
            "inc" => "Increment operations"
            _ => "Plugin for Nushell"
        }

        {
            name: $plugin.name
            version: $plugin.version
            status: $status
            description: $description
        }
    }
}

# Register a plugin with Nushell
export def register-plugin [
    plugin_name: string  # Name of plugin binary (e.g., nu_plugin_auth)
] {
    let plugin_path = (which $plugin_name | get path.0?)

    if ($plugin_path | is-empty) {
        error make {
            msg: $"❌ Plugin ($plugin_name) not found in PATH"
            label: {
                text: "Plugin binary not available"
                span: (metadata $plugin_name).span
            }
        }
    }

    print $"(_ansi cyan)Registering plugin: ($plugin_name)(_ansi reset)"

    let result = (do -i {
        plugin add $plugin_path
        true
    })

    if $result == null {
        error make {
            msg: $"❌ Failed to register plugin: ($plugin_name)"
            label: {
                text: "Registration failed"
                span: (metadata $plugin_name).span
            }
        }
    }

    print $"(_ansi green)✓ Plugin registered successfully(_ansi reset)"
}

# Test plugin functionality
export def test-plugin [
    plugin_name: string  # auth, kms, secretumvault, tera, nickel
] {
    match $plugin_name {
        "auth" => {
            print $"(_ansi cyan)Testing auth plugin...(_ansi reset)"
            let status = (plugin-auth-status)
            print $"Plugin available: ($status.plugin_available)"
            print $"Plugin enabled: ($status.plugin_enabled)"
            print $"Mode: ($status.mode)"
            $status
        }
        "kms" => {
            print $"(_ansi cyan)Testing KMS plugin...(_ansi reset)"
            let info = (plugin-kms-info)
            print $"Plugin available: ($info.plugin_available)"
            print $"Plugin enabled: ($info.plugin_enabled)"
            print $"Default backend: ($info.default_backend)"
            print $"Mode: ($info.mode)"
            $info
        }
        "secretumvault" => {
            print $"(_ansi cyan)Testing SecretumVault plugin...(_ansi reset)"
            let info = (plugin-secretumvault-info)
            print $"Plugin available: ($info.plugin_available)"
            print $"Plugin enabled: ($info.plugin_enabled)"
            print $"Service URL: ($info.service_url)"
            print $"Mount point: ($info.mount_point)"
            print $"Default key: ($info.default_key)"
            print $"Mode: ($info.mode)"
            $info
        }
        "tera" => {
            print $"(_ansi cyan)Testing tera plugin...(_ansi reset)"
            let installed = (version).installed_plugins
            let available = ($installed | str contains "tera")
            print $"Plugin registered: ($available)"
            {plugin_available: $available}
        }
        "nickel" => {
            print $"(_ansi cyan)Testing Nickel plugin...(_ansi reset)"
            let installed = (version).installed_plugins
            let available = ($installed | str contains "nickel")
            print $"Plugin registered: ($available)"
            {plugin_available: $available}
        }
        _ => {
            error make {
                msg: $"❌ Unknown plugin: ($plugin_name)"
                label: {
                    text: "Valid plugins: auth, kms, secretumvault, tera, nickel"
                    span: (metadata $plugin_name).span
                }
            }
        }
    }
}

# Get plugin build information
export def plugin-build-info [] {
    let plugin_dir = ($env.PWD | path join "_nushell-plugins")

    if not ($plugin_dir | path exists) {
        return {
            plugins_dir: $plugin_dir
            exists: false
            message: "Plugin source directory not found"
        }
    }

    let subdirs = (ls $plugin_dir | where type == dir | get name)

    {
        plugins_dir: $plugin_dir
        exists: true
        available_sources: $subdirs
    }
}

# Build plugins from source
export def build-plugins [
    --plugin: string = ""  # Specific plugin to build (empty = all)
] {
    let plugin_dir = ($env.PWD | path join "_nushell-plugins")

    if not ($plugin_dir | path exists) {
        error make {
            msg: "❌ Plugin source directory not found"
            label: {
                text: $"Expected at: ($plugin_dir)"
            }
        }
    }

    let plugins_to_build = if ($plugin | is-empty) {
        ls $plugin_dir | where type == dir | get name
    } else {
        let specific_path = ($plugin_dir | path join $plugin)
        if not ($specific_path | path exists) {
            error make {
                msg: $"❌ Plugin source not found: ($plugin)"
                label: {
                    text: $"Path: ($specific_path)"
                    span: (metadata $plugin).span
                }
            }
        }
        [$specific_path]
    }

    for plugin_path in $plugins_to_build {
        let plugin_name = ($plugin_path | path basename)
        print $"\n(_ansi cyan_bold)Building ($plugin_name)...(_ansi reset)"

        cd $plugin_path
        print $"(_ansi default_dimmed)Running cargo build --release...(_ansi reset)"

        let result = (do -i {
            cargo build --release
        })

        if $result == null {
            print $"(_ansi red)❌ Failed to build ($plugin_name)(_ansi reset)"
        } else {
            print $"(_ansi green)✓ ($plugin_name) built successfully(_ansi reset)"
        }
    }
}
