# Provider Creation Tool
# Quickly create a new provider with proper structure and templates

use ../core/nulib/lib_provisioning/utils/logging.nu *
use ../core/nulib/lib_provisioning/providers/registry.nu *

# Create a new provider
export def main [
    provider_name: string          # Name of the new provider (e.g., "digitalocean")
    --description: string = ""     # Description of the provider
    --api-base: string = ""        # Base API URL for the provider
    --auth-type: string = "token"  # Authentication type (token, key, oauth)
    --template: string = "cloud"   # Template type (cloud, container, baremetal)
    --dry-run                      # Show what would be created without executing
] {
    log-section "Creating new provider: $provider_name" "create-provider"

    # Validate provider name
    if ($provider_name | str contains " ") {
        log-error "Provider name cannot contain spaces" "validation"
        return
    }

    if ($provider_name | str length) < 2 {
        log-error "Provider name must be at least 2 characters" "validation"
        return
    }

    # Check if provider already exists
    let provider_path = $"../extensions/providers/($provider_name)"
    if ($provider_path | path exists) {
        log-error $"Provider ($provider_name) already exists at ($provider_path)" "validation"
        return
    }

    # Create directory structure
    let directories = [
        $"../extensions/providers/($provider_name)"
        $"../extensions/providers/($provider_name)/nulib"
        $"../extensions/providers/($provider_name)/nulib/($provider_name)"
    ]

    if $dry_run {
        log-info "DRY RUN MODE - No files will be created" "create-provider"
        print "Directories to create:"
        for dir in $directories {
            print $"  📁 ($dir)"
        }
    } else {
        for dir in $directories {
            mkdir $dir
            log-success $"Created directory: ($dir)" "create-provider"
        }
    }

    # Generate provider metadata
    let metadata = generate_provider_metadata $provider_name $description $template

    # Generate provider adapter
    let adapter_content = generate_provider_adapter $provider_name $template $auth_type

    # Generate provider implementation
    let implementation_content = generate_provider_implementation $provider_name $template $api_base $auth_type

    # Create files
    let files = [
        {
            path: $"../extensions/providers/($provider_name)/provider.nu"
            content: $adapter_content
            description: "Provider adapter implementing standard interface"
        }
        {
            path: $"../extensions/providers/($provider_name)/nulib/($provider_name)/servers.nu"
            content: $implementation_content
            description: "Provider-specific implementation functions"
        }
        {
            path: $"../extensions/providers/($provider_name)/README.md"
            content: (generate_provider_readme $provider_name $description $auth_type)
            description: "Provider documentation"
        }
    ]

    if $dry_run {
        print "\nFiles to create:"
        for file in $files {
            print $"  📄 ($file.path) - ($file.description)"
        }
    } else {
        for file in $files {
            $file.content | save $file.path
            log-success $"Created file: ($file.path)" "create-provider"
        }
    }

    # Generate usage examples
    let usage_examples = generate_usage_examples $provider_name

    if not $dry_run {
        $usage_examples | save $"../extensions/providers/($provider_name)/USAGE.md"
        log-success "Created usage examples" "create-provider"
    }

    # Show next steps
    log-section "Next Steps" "create-provider"
    let next_steps = [
        $"1. Edit authentication in: ../extensions/providers/($provider_name)/nulib/($provider_name)/servers.nu"
        $"2. Implement provider-specific API calls"
        $"3. Test provider: nu -c \"use provisioning/core/nulib/lib_provisioning/providers/loader.nu *; load-provider '($provider_name)'\""
        $"4. Validate interface: nu -c \"use provisioning/core/nulib/lib_provisioning/providers/interface.nu *; validate-provider-interface '($provider_name)'\""
        $"5. Add provider to infrastructure configs"
        $"6. Run tests: ./provisioning/tools/test-provider-agnostic.nu"
    ]

    for step in $next_steps {
        print $step
    }

    if not $dry_run {
        log-success $"Provider ($provider_name) created successfully!" "create-provider"
    } else {
        log-info "Use --dry-run=false to create the provider" "create-provider"
    }
}

# Generate provider metadata
def generate_provider_metadata [name: string, description: string, template: string]: nothing -> record {
    let desc = if ($description | is-empty) {
        match $template {
            "cloud" => $"($name | str title-case) cloud provider"
            "container" => $"($name | str title-case) container platform"
            "baremetal" => $"($name | str title-case) bare metal provider"
            _ => $"($name | str title-case) infrastructure provider"
        }
    } else {
        $description
    }

    let capabilities = match $template {
        "cloud" => {
            server_management: true
            network_management: true
            storage_management: true
            load_balancer: true
            dns_management: false
            cdn: false
            backup_service: true
            monitoring: false
            logging: false
            auto_scaling: true
            spot_instances: false
            containers: false
            serverless: false
            multi_region: true
            encryption_at_rest: true
            encryption_in_transit: true
            compliance_certifications: []
        }
        "container" => {
            server_management: false
            network_management: true
            storage_management: true
            load_balancer: false
            dns_management: false
            cdn: false
            backup_service: false
            monitoring: false
            logging: false
            auto_scaling: true
            spot_instances: false
            containers: true
            serverless: false
            multi_region: false
            encryption_at_rest: false
            encryption_in_transit: true
            compliance_certifications: []
        }
        "baremetal" => {
            server_management: true
            network_management: false
            storage_management: true
            load_balancer: false
            dns_management: false
            cdn: false
            backup_service: false
            monitoring: false
            logging: false
            auto_scaling: false
            spot_instances: false
            containers: true
            serverless: false
            multi_region: false
            encryption_at_rest: false
            encryption_in_transit: false
            compliance_certifications: []
        }
        _ => {
            server_management: true
            network_management: false
            storage_management: false
            load_balancer: false
            dns_management: false
            cdn: false
            backup_service: false
            monitoring: false
            logging: false
            auto_scaling: false
            spot_instances: false
            containers: false
            serverless: false
            multi_region: false
            encryption_at_rest: false
            encryption_in_transit: false
            compliance_certifications: []
        }
    }

    {
        name: $name
        description: $desc
        capabilities: $capabilities
    }
}

# Generate provider adapter content
def generate_provider_adapter [name: string, template: string, auth_type: string]: nothing -> string {
    let name_title = ($name | str title-case)
    let metadata = generate_provider_metadata $name "" $template

    $"# ($name_title) Provider Adapter
# Implements the standard provider interface for ($name_title)

use nulib/($name)/servers.nu *

# Provider metadata
export def get-provider-metadata []: nothing -> record {
    {
        name: \"($name)\"
        version: \"1.0.0\"
        description: \"($metadata.description)\"
        capabilities: ($metadata.capabilities | to nuon)
    }
}

# Server query operations
export def query_servers [
    find?: string
    cols?: string
]: nothing -> list {
    let str_find = if \\$find != null { \\$find } else { \"\" }
    let str_cols = if \\$cols != null { \\$cols } else { \"\" }
    ($name)_query_servers \\$str_find \\$str_cols
}

# Server information operations
export def server_info [
    server: record
    check: bool
    find?: string
    cols?: string
]: nothing -> record {
    ($name)_server_info \\$server \\$check
}

# Server existence and status operations
export def server_exists [
    server: record
    error_exit: bool
]: nothing -> bool {
    ($name)_server_exists \\$server \\$error_exit
}

export def server_is_running [
    server: record
    error_exit: bool
]: nothing -> bool {
    ($name)_server_is_running \\$server \\$error_exit
}

# Server lifecycle operations
export def check_server_requirements [
    settings: record
    server: record
    check: bool
]: nothing -> bool {
    ($name)_check_server_requirements \\$settings \\$server \\$check
}

export def create_server [
    settings: record
    server: record
    check: bool
    wait: bool
]: nothing -> bool {
    ($name)_create_server \\$settings \\$server \\$check \\$wait
}

export def delete_server [
    settings: record
    server: record
    keep_storage: bool
    error_exit: bool
]: nothing -> bool {
    ($name)_delete_server \\$settings \\$server \\$keep_storage \\$error_exit
}

export def delete_server_storage [
    settings: record
    server: record
    error_exit: bool
]: nothing -> bool {
    ($name)_delete_server_storage \\$settings \\$server \\$error_exit
}

export def post_create_server [
    settings: record
    server: record
    check: bool
]: nothing -> bool {
    ($name)_post_create_server \\$settings \\$server \\$check
}

export def modify_server [
    settings: record
    server: record
    new_values: list
    error_exit: bool
]: nothing -> bool {
    ($name)_modify_server \\$settings \\$server \\$new_values \\$error_exit
}

# Server state management
export def server_state [
    server: record
    new_state: string
    error_exit: bool
    wait: bool
    settings: record
]: nothing -> bool {
    ($name)_server_state \\$server \\$new_state \\$error_exit \\$wait \\$settings
}

# Network operations
export def get_ip [
    settings: record
    server: record
    ip_type: string
    error_exit: bool
]: nothing -> string {
    let use_type = match \\$ip_type {
        \"\\$network_public_ip\" => \"public\"
        \"\\$network_private_ip\" => \"private\"
        _ => \\$ip_type
    }

    let result = (($name)_get_ip \\$settings \\$server \\$use_type \\$error_exit)
    \\$result | str trim
}

export def servers_ips [
    settings: record
    data: list
    prov?: string
    serverpos?: int
]: nothing -> list {
    ($name)_servers_ips \\$settings \\$data \\$prov \\$serverpos
}

# Infrastructure operations
export def load_infra_servers_info [
    settings: record
    server: record
    error_exit: bool
]: nothing -> record {
    ($name)_load_infra_servers_info \\$settings \\$server \\$error_exit
}

export def load_infra_storages_info [
    settings: record
    server: record
    error_exit: bool
]: nothing -> record {
    ($name)_load_infra_storages_info \\$settings \\$server \\$error_exit
}

export def get_infra_storage [
    server: record
    settings: record
    cloud_data: record
    error_exit: bool
]: nothing -> list {
    ($name)_get_infra_storage \\$server \\$settings \\$cloud_data \\$error_exit
}

export def get_infra_item [
    server: record
    settings: record
    cloud_data: record
    error_exit: bool
]: nothing -> record {
    ($name)_get_infra_item \\$server \\$settings \\$cloud_data \\$error_exit
}

export def get_infra_price [
    server: record
    data: record
    key: string
    error_exit: bool
    price_col?: string
]: nothing -> float {
    ($name)_get_infra_price \\$server \\$data \\$key \\$error_exit \\$price_col
}

# Cache operations
export def start_cache_info [
    settings: record
    server: record
]: nothing -> nothing {
    ($name)_start_cache_info \\$settings \\$server
}

export def create_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    ($name)_create_cache \\$settings \\$server \\$error_exit
}

export def read_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    ($name)_read_cache \\$settings \\$server \\$error_exit
}

export def clean_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    ($name)_clean_cache \\$settings \\$server \\$error_exit
}

export def ip_from_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> string {
    ($name)_ip_from_cache \\$settings \\$server \\$error_exit
}

# Provider metadata operations
export def on_prov_server [
    server: record
]: nothing -> string {
    ($name)_on_prov_server \\$server
}

# Provider validation
export def validate_provider []: nothing -> record {
    {
        provider: \"($name)\"
        valid: true
        interface_version: \"1.0.0\"
        capabilities: (get-provider-metadata).capabilities
        last_validated: (date now)
    }
}
"
}

# Generate provider implementation content
def generate_provider_implementation [name: string, template: string, api_base: string, auth_type: string]: nothing -> string {
    let name_title = ($name | str title-case)
    let auth_var = match $auth_type {
        "token" => $"($name | str upcase)_TOKEN"
        "key" => $"($name | str upcase)_API_KEY"
        "oauth" => $"($name | str upcase)_CLIENT_ID"
        _ => $"($name | str upcase)_TOKEN"
    }

    let api_url = if ($api_base | is-empty) {
        $"https://api.($name).com"
    } else {
        $api_base
    }

    let implementation = match $template {
        "cloud" => generate_cloud_implementation $name $auth_var $api_url
        "container" => generate_container_implementation $name
        "baremetal" => generate_baremetal_implementation $name
        _ => generate_generic_implementation $name $auth_var $api_url
    }

    $"# ($name_title) Provider Implementation
# Provider-specific functions for ($name_title)

use ../../core/nulib/lib_provisioning/utils/logging.nu *

# Authentication check
def check_auth []: nothing -> bool {
    if (\\$env | get -o ($auth_var)) == null {
        log-error \"($auth_var) environment variable required\" \"auth\"
        return false
    }
    true
}

($implementation)
"
}

# Generate cloud provider implementation
def generate_cloud_implementation [name: string, auth_var: string, api_url: string]: nothing -> string {
    $"# Cloud provider implementation for ($name)

export def ($name)_query_servers [find?: string, cols?: string]: nothing -> list {
    if not (check_auth) { return [] }

    let auth_header = { Authorization: \\$\"Bearer (\\$env.($auth_var))\" }

    let result = (do {
        let servers = (http get \\$\"($api_url)/servers\" --headers \\$auth_header)

        # Filter results if find parameter provided
        let filtered = if (\\$find != null) and (\\$find != \"\") {
            \\$servers | where {|server| \\$server.name =~ \\$find}
        } else {
            \\$servers
        }

        # Select columns if specified
        if (\\$cols != null) and (\\$cols != \"\") {
            let field_list = (\\$cols | split row \",\")
            \\$filtered | select ...(\\$field_list)
        } else {
            \\$filtered | select name status region instance_type public_ip
        }
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"Failed to query servers: operation failed\" \"($name)\"
        []
    } else {
        \\$result.stdout
    }
}

export def ($name)_create_server [settings: record, server: record, check: bool, wait: bool]: nothing -> bool {
    if not (check_auth) { return false }

    let payload = {
        name: \\$server.hostname
        region: (\\$server.zone? | default \"us-east-1\")
        instance_type: (\\$server.plan? | default \"t3.micro\")
        image: (\\$server.image? | default \"ubuntu-20.04\")
    }

    if \\$check {
        log-info \\$\"Would create ($name) server: (\\$payload)\" \"($name)\"
        return true
    }

    let result = (do {
        let auth_header = { Authorization: \\$\"Bearer (\\$env.($auth_var))\" }
        let create_result = (http post \\$\"($api_url)/servers\"
            --headers \\$auth_header
            --content-type application/json
            \\$payload)

        if \\$wait {
            # Poll for server to be ready
            mut attempts = 0
            while \\$attempts < 60 {  # 5 minutes max
                let status = (($name)_server_exists \\$server false)
                if \\$status {
                    log-success \\$\"Server (\\$server.hostname) is ready\" \"($name)\"
                    break
                }
                sleep 5sec
                \\$attempts += 1
            }
        }

        log-success \\$\"Created server: (\\$server.hostname)\" \"($name)\"
        true
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"Failed to create server: operation failed\" \"($name)\"
        false
    } else {
        true
    }
}

export def ($name)_server_exists [server: record, error_exit: bool]: nothing -> bool {
    if not (check_auth) { return false }

    let result = (do {
        let auth_header = { Authorization: \\$\"Bearer (\\$env.($auth_var))\" }
        let servers = (http get \\$\"($api_url)/servers\" --headers \\$auth_header)
        let found = (\\$servers | where name == \\$server.hostname)
        (\\$found | length) > 0
    } | complete)

    if \\$result.exit_code != 0 {
        if \\$error_exit {
            log-error \"Error checking server existence: operation failed\" \"($name)\"
            exit 1
        }
        false
    } else {
        true
    }
}

export def ($name)_get_ip [settings: record, server: record, ip_type: string, error_exit: bool]: nothing -> string {
    if not (check_auth) { return \"\" }

    let result = (do {
        let auth_header = { Authorization: \\$\"Bearer (\\$env.($auth_var))\" }
        let servers = (http get \\$\"($api_url)/servers\" --headers \\$auth_header)
        let found = (\\$servers | where name == \\$server.hostname | get 0)

        match \\$ip_type {
            \"public\" => (\\$found.public_ip? | default \"\")
            \"private\" => (\\$found.private_ip? | default \"\")
            _ => (\\$found.public_ip? | default \"\")
        }
    } | complete)

    if \\$result.exit_code != 0 {
        if \\$error_exit {
            log-error \"Error getting IP: operation failed\" \"($name)\"
            exit 1
        }
        \"\"
    } else {
        \\$result.stdout
    }
}

export def ($name)_delete_server [settings: record, server: record, keep_storage: bool, error_exit: bool]: nothing -> bool {
    if not (check_auth) { return false }

    let result = (do {
        let auth_header = { Authorization: \\$\"Bearer (\\$env.($auth_var))\" }
        http delete \\$\"($api_url)/servers/(\\$server.hostname)\" --headers \\$auth_header

        log-success \\$\"Deleted server: (\\$server.hostname)\" \"($name)\"
        true
    } | complete)

    if \\$result.exit_code != 0 {
        if \\$error_exit {
            log-error \"Error deleting server: operation failed\" \"($name)\"
            exit 1
        }
        false
    } else {
        true
    }
}

# Implement other required functions...
export def ($name)_server_info [server: record, check: bool]: nothing -> record {
    { hostname: \\$server.hostname, provider: \"($name)\", status: \"unknown\" }
}

export def ($name)_server_is_running [server: record, error_exit: bool]: nothing -> bool {
    # Implementation depends on your provider's API
    true
}

export def ($name)_check_server_requirements [settings: record, server: record, check: bool]: nothing -> bool {
    true
}

export def ($name)_delete_server_storage [settings: record, server: record, error_exit: bool]: nothing -> bool {
    true
}

export def ($name)_post_create_server [settings: record, server: record, check: bool]: nothing -> bool {
    true
}

export def ($name)_modify_server [settings: record, server: record, new_values: list, error_exit: bool]: nothing -> bool {
    true
}

export def ($name)_server_state [server: record, new_state: string, error_exit: bool, wait: bool, settings: record]: nothing -> bool {
    true
}

export def ($name)_servers_ips [settings: record, data: list, prov?: string, serverpos?: int]: nothing -> list {
    []
}

export def ($name)_load_infra_servers_info [settings: record, server: record, error_exit: bool]: nothing -> record {
    { provider: \"($name)\", server: \\$server.hostname }
}

export def ($name)_load_infra_storages_info [settings: record, server: record, error_exit: bool]: nothing -> record {
    { provider: \"($name)\", storage: \"managed\" }
}

export def ($name)_get_infra_storage [server: record, settings: record, cloud_data: record, error_exit: bool]: nothing -> list {
    []
}

export def ($name)_get_infra_item [server: record, settings: record, cloud_data: record, error_exit: bool]: nothing -> record {
    { provider: \"($name)\", hostname: \\$server.hostname }
}

export def ($name)_get_infra_price [server: record, data: record, key: string, error_exit: bool, price_col?: string]: nothing -> float {
    0.0
}

export def ($name)_start_cache_info [settings: record, server: record]: nothing -> nothing {
    # No-op
}

export def ($name)_create_cache [settings: record, server: record, error_exit: bool]: nothing -> nothing {
    # No-op
}

export def ($name)_read_cache [settings: record, server: record, error_exit: bool]: nothing -> nothing {
    # No-op
}

export def ($name)_clean_cache [settings: record, server: record, error_exit: bool]: nothing -> nothing {
    # No-op
}

export def ($name)_ip_from_cache [settings: record, server: record, error_exit: bool]: nothing -> string {
    \"\"
}

export def ($name)_on_prov_server [server: record]: nothing -> string {
    \\$\"Using ($name) provider for (\\$server.hostname)\"
}
"
}

# Generate container provider implementation
def generate_container_implementation [name: string]: nothing -> string {
    $"# Container provider implementation for ($name)

export def ($name)_query_servers [find?: string, cols?: string]: nothing -> list {
    let result = (do {
        let containers = (docker ps --format json | from json)

        let filtered = if (\\$find != null) and (\\$find != \"\") {
            \\$containers | where {|container| \\$container.Names =~ \\$find}
        } else {
            \\$containers
        }

        if (\\$cols != null) and (\\$cols != \"\") {
            let field_list = (\\$cols | split row \",\")
            \\$filtered | select ...(\\$field_list)
        } else {
            \\$filtered | select Names State Status Image
        }
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"Failed to query containers: operation failed\" \"($name)\"
        []
    } else {
        \\$result.stdout
    }
}

export def ($name)_create_server [settings: record, server: record, check: bool, wait: bool]: nothing -> bool {
    let image = (\\$server.image? | default \"ubuntu:20.04\")
    let command = [\"docker\", \"run\", \"-d\", \"--name\", \\$server.hostname, \\$image]

    if \\$check {
        log-info \\$\"Would create container: (\\$command | str join ' ')\" \"($name)\"
        return true
    }

    let result = (do {
        let container_result = (run-external \"docker\" \"run\" \"-d\" \"--name\" \\$server.hostname \\$image)
        log-success \\$\"Created container: (\\$server.hostname)\" \"($name)\"
        true
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"Failed to create container: operation failed\" \"($name)\"
        false
    } else {
        true
    }
}

# Implement other required functions for container platform...
"
}

# Generate baremetal provider implementation
def generate_baremetal_implementation [name: string]: nothing -> string {
    $"# Bare metal provider implementation for ($name)

export def ($name)_query_servers [find?: string, cols?: string]: nothing -> list {
    let result = (do {
        # Read from inventory file or configuration
        let inventory_file = \\$\"inventory.(\\$name).yaml\"
        if not (\\$inventory_file | path exists) {
            log-warning \\$\"Inventory file not found: (\\$inventory_file)\" \"($name)\"
            return []
        }

        let inventory = (open \\$inventory_file | from yaml)
        let servers = \\$inventory.servers

        let filtered = if (\\$find != null) and (\\$find != \"\") {
            \\$servers | where {|server| \\$server.hostname =~ \\$find}
        } else {
            \\$servers
        }

        if (\\$cols != null) and (\\$cols != \"\") {
            let field_list = (\\$cols | split row \",\")
            \\$filtered | select ...(\\$field_list)
        } else {
            \\$filtered | select hostname ip_address status
        }
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"Failed to query servers: operation failed\" \"($name)\"
        []
    } else {
        \\$result.stdout
    }
}

export def ($name)_create_server [settings: record, server: record, check: bool, wait: bool]: nothing -> bool {
    # For bare metal, \"creation\" means ensuring server is accessible
    if \\$check {
        log-info \\$\"Would validate bare metal server: (\\$server.hostname)\" \"($name)\"
        return true
    }

    let result = (do {
        # Test SSH connectivity
        let test_result = (ssh -o ConnectTimeout=5 \\$server.hostname \"echo 'connection test'\")
        if (\\$test_result | str contains \"connection test\") {
            log-success \\$\"Bare metal server (\\$server.hostname) is accessible\" \"($name)\"
            true
        } else {
            log-error \\$\"Cannot connect to bare metal server (\\$server.hostname)\" \"($name)\"
            false
        }
    } | complete)

    if \\$result.exit_code != 0 {
        log-error \"SSH connection failed: operation failed\" \"($name)\"
        false
    } else {
        true
    }
}

# Implement other required functions for bare metal...
"
}

# Generate generic provider implementation
def generate_generic_implementation [name: string, auth_var: string, api_url: string]: nothing -> string {
    $"# Generic provider implementation for ($name)

export def ($name)_query_servers [find?: string, cols?: string]: nothing -> list {
    # TODO: Implement your provider's server listing logic
    log-warning \"($name)_query_servers not yet implemented\" \"($name)\"
    []
}

export def ($name)_create_server [settings: record, server: record, check: bool, wait: bool]: nothing -> bool {
    # TODO: Implement your provider's server creation logic
    if \\$check {
        log-info \\$\"Would create server: (\\$server.hostname)\" \"($name)\"
        return true
    }

    log-warning \"($name)_create_server not yet implemented\" \"($name)\"
    false
}

# TODO: Implement all other required functions...
"
}

# Generate provider README
def generate_provider_readme [name: string, description: string, auth_type: string]: nothing -> string {
    let name_title = ($name | str title-case)
    let auth_var = match $auth_type {
        "token" => $"($name | str upcase)_TOKEN"
        "key" => $"($name | str upcase)_API_KEY"
        "oauth" => $"($name | str upcase)_CLIENT_ID"
        _ => $"($name | str upcase)_TOKEN"
    }

    $"# ($name_title) Provider

($description)

## Authentication

Set the following environment variable:

```bash
export ($auth_var)=\"your-($auth_type)-here\"
```

## Configuration

Add servers using the ($name) provider in your KCL configuration:

```kcl
servers = [
    {
        hostname = \"my-server\"
        provider = \"($name)\"
        zone = \"region-1\"
        plan = \"small\"
        image = \"ubuntu-20.04\"
    }
]
```

## Features

- ✅ Server management
- ✅ Basic operations
- ⚠️  Advanced features (in development)

## Usage

```bash
# Query servers
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; query_servers\"

# Test provider
./provisioning/tools/test-provider-agnostic.nu
```

## Development

This provider was generated using the provider creation tool. See `USAGE.md` for implementation examples.

## Status

🚧 **Work in Progress** - This provider needs implementation of core functions.

## Support

- Check the [Provider Development Guide](../../../docs/development/QUICK_PROVIDER_GUIDE.md)
- Review existing providers for implementation patterns
- Run tests with: `./provisioning/tools/test-provider-agnostic.nu`
"
}

# Generate usage examples
def generate_usage_examples [name: string]: nothing -> string {
    let name_title = ($name | str title-case)

    $"# ($name_title) Provider Usage Examples

## Basic Server Operations

### Query Servers

```bash
# List all servers
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; query_servers\"

# Find servers by name
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; query_servers 'web'\"

# Select specific columns
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; query_servers '' 'name,status,region'\"
```

### Server Information

```bash
# Get detailed server info
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; server_info {hostname: 'my-server'} false\"

# Check if server exists
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; server_exists {hostname: 'my-server'} false\"
```

## Infrastructure Configuration

### KCL Configuration Example

```kcl
# workspace/infra/example/servers.k
servers = [
    {
        hostname = \"web-01\"
        provider = \"($name)\"
        zone = \"us-east-1\"
        plan = \"t3.micro\"
        image = \"ubuntu-20.04\"
        network_public_ip = \"auto\"
        network_private_ip = \"auto\"
    }
    {
        hostname = \"db-01\"
        provider = \"($name)\"
        zone = \"us-east-1\"
        plan = \"t3.small\"
        image = \"ubuntu-20.04\"
        network_public_ip = \"auto\"
        network_private_ip = \"auto\"
    }
]
```

### Multi-Provider Configuration

```kcl
# Mix ($name) with other providers
servers = [
    {
        hostname = \"compute-01\"
        provider = \"($name)\"
        zone = \"us-east-1\"
        plan = \"large\"
    }
    {
        hostname = \"backup-01\"
        provider = \"upcloud\"
        zone = \"us-nyc1\"
        plan = \"1xCPU-2GB\"
    }
]
```

## Provider Testing

### Test Provider Loading

```bash
# Test provider registration
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/registry.nu *; init-provider-registry; is-provider-available '($name)'\"

# Test provider loading
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/loader.nu *; load-provider '($name)'\"

# Validate interface compliance
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/interface.nu *; validate-provider-interface '($name)'\"
```

### Run Full Test Suite

```bash
# Run all provider tests
./provisioning/tools/test-provider-agnostic.nu run-all-tests

# Test specific provider
./provisioning/tools/test-provider-agnostic.nu test-provider-loading
```

## Integration with Provisioning System

### Using with Core CLI

```bash
# Create servers using the ($name) provider
./provisioning/core/cli/provisioning server create --infra example --check

# List servers from ($name) provider
./provisioning/core/cli/provisioning server list --provider ($name)

# Get server info
./provisioning/core/cli/provisioning server info web-01
```

### Provider-Agnostic Operations

```bash
# Query servers across all providers
nu -c \"use provisioning/extensions/providers/prov_lib/middleware_provider_agnostic.nu *; mw_query_servers {data: {servers: []}}\"

# Get provider status
nu -c \"use provisioning/extensions/providers/prov_lib/middleware_provider_agnostic.nu *; mw_provider_status\"

# Multi-provider deployment
nu -c \"use provisioning/extensions/providers/prov_lib/middleware_provider_agnostic.nu *; mw_deploy_multi_provider_infra \\$settings \\$plan\"
```

## Debugging

### Check Provider Status

```bash
# List all providers
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/registry.nu *; list-providers\"

# Get provider capabilities
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/registry.nu *; get-provider-capabilities-for '($name)'\"

# Check provider health
nu -c \"use provisioning/core/nulib/lib_provisioning/providers/loader.nu *; check-provider-health '($name)'\"
```

### Common Issues

1. **Provider not found**
   ```bash
   # Refresh provider registry
   nu -c \"use provisioning/core/nulib/lib_provisioning/providers/registry.nu *; init-provider-registry\"
   ```

2. **Authentication failed**
   ```bash
   # Check environment variables
   env | grep ($name | str upcase)
   ```

3. **Interface validation failed**
   ```bash
   # Check missing functions
   nu -c \"use provisioning/core/nulib/lib_provisioning/providers/interface.nu *; validate-provider-interface '($name)'\"
   ```

## Advanced Usage

### Custom Provider Functions

```bash
# Call provider-specific functions directly
nu -c \"use provisioning/extensions/providers/($name)/nulib/($name)/servers.nu *; ($name)_query_servers\"
```

### Provider Capabilities

```bash
# Check what the provider supports
nu -c \"use provisioning/extensions/providers/($name)/provider.nu *; get-provider-metadata\"
```

## Next Steps

1. Implement missing provider functions in `nulib/($name)/servers.nu`
2. Add authentication and API integration
3. Test with real infrastructure
4. Add provider-specific features and optimizations
5. Contribute improvements back to the project
"
}

# Show help
export def help []: nothing -> nothing {
    let help_text = $"
Provider Creation Tool

USAGE:
    ./provisioning/tools/create-provider.nu <provider_name> [options]

ARGUMENTS:
    provider_name    Name of the new provider (e.g., 'digitalocean', 'linode')

OPTIONS:
    --description    Description of the provider (optional)
    --api-base       Base API URL for the provider (optional)
    --auth-type      Authentication type: token, key, oauth (default: token)
    --template       Template type: cloud, container, baremetal (default: cloud)
    --dry-run        Show what would be created without executing

EXAMPLES:
    # Create a cloud provider with token auth
    ./provisioning/tools/create-provider.nu digitalocean --description \"DigitalOcean cloud provider\"

    # Create a container platform provider
    ./provisioning/tools/create-provider.nu podman --template container

    # Create a bare metal provider
    ./provisioning/tools/create-provider.nu datacenter --template baremetal

    # Preview what would be created
    ./provisioning/tools/create-provider.nu newprovider --dry-run

TEMPLATES:
    cloud       - Full cloud provider with API integration (AWS, GCP, Azure style)
    container   - Container platform provider (Docker, Podman style)
    baremetal   - Bare metal or existing server provider (Local, SSH style)

NEXT STEPS:
    1. Run the tool to create provider structure
    2. Implement authentication in the generated files
    3. Add provider-specific API calls
    4. Test with: ./provisioning/tools/test-provider-agnostic.nu
    5. Validate interface compliance
    6. Add to infrastructure configurations

For more information, see docs/development/QUICK_PROVIDER_GUIDE.md
"

    print $help_text
}
