# AWS Provider Adapter
# Implements the standard provider interface for AWS

use nulib/aws/env.nu
use nulib/aws/servers.nu *
use nulib/aws/cache.nu *
use nulib/aws/prices.nu *

# Provider metadata
export def get-provider-metadata []: nothing -> record {
    {
        name: "aws"
        version: "1.0.0"
        description: "Amazon Web Services provider"
        capabilities: {
            server_management: true
            network_management: true
            storage_management: true
            load_balancer: true
            dns_management: false
            cdn: true
            backup_service: true
            monitoring: true
            logging: true
            auto_scaling: true
            spot_instances: true
            containers: true
            serverless: true
            multi_region: true
            encryption_at_rest: true
            encryption_in_transit: true
            compliance_certifications: ["SOC2", "ISO27001", "PCI-DSS", "HIPAA"]
        }
    }
}

# 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 { "" }
    aws_query_servers $str_find $str_cols
}

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

# Server existence and status operations
export def server_exists [
    server: record
    error_exit: bool
]: nothing -> bool {
    aws_server_exists $server $error_exit
}

export def server_is_running [
    server: record
    error_exit: bool
]: nothing -> bool {
    aws_server_is_running $server $error_exit
}

# Server lifecycle operations
export def check_server_requirements [
    settings: record
    server: record
    check: bool
]: nothing -> bool {
    aws_check_server_requirements $settings $server $check
}

export def create_server [
    settings: record
    server: record
    check: bool
    wait: bool
]: nothing -> bool {
    # AWS doesn't have a direct create_server function, it uses server_state
    # Create server by setting state to "started"
    try {
        aws_server_state $server "started" true $wait $settings
        true
    } catch {
        false
    }
}

export def delete_server [
    settings: record
    server: record
    keep_storage: bool
    error_exit: bool
]: nothing -> bool {
    aws_delete_server $settings $server $keep_storage $error_exit
}

export def delete_server_storage [
    settings: record
    server: record
    error_exit: bool
]: nothing -> bool {
    aws_delete_server_storage $settings $server $error_exit
}

export def post_create_server [
    settings: record
    server: record
    check: bool
]: nothing -> bool {
    aws_post_create_server $settings $server $check
}

export def modify_server [
    settings: record
    server: record
    new_values: list
    error_exit: bool
]: nothing -> bool {
    aws_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 {
    aws_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 = (aws_server [ "get_ip", $use_type ] --server $server --settings $settings)
    $result | str trim
}

export def servers_ips [
    settings: record
    data: list
    prov?: string
    serverpos?: int
]: nothing -> list {
    # AWS-specific implementation for getting IPs from multiple servers
    mut result = []
    mut index = -1

    for srv in $data {
        $index += 1
        let settings_server = ($settings.data.servers | where {|it| $it.hostname == $srv.hostname})
        if ($settings_server | length) == 0 { continue }
        let provider = ($settings_server | get -o 0 | get -o provider | default "")
        if $prov != null and $provider != "aws" { continue }
        if $serverpos != null and $serverpos != $index { continue }

        if $srv.ip_addresses? != null {
            $result = ($result | append ($srv.ip_addresses? |
                each {|it| { hostname: $srv.hostname, ip: $it.address, access: $it.access, family: $it.family }} |
                flatten
            ))
        }
    }

    $result
}

# Infrastructure operations
export def load_infra_servers_info [
    settings: record
    server: record
    error_exit: bool
]: nothing -> record {
    aws_load_infra_servers_info $settings $server $error_exit
}

export def load_infra_storages_info [
    settings: record
    server: record
    error_exit: bool
]: nothing -> record {
    aws_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 {
    aws_get_item_for_storage $server $settings $cloud_data
}

export def get_infra_item [
    server: record
    settings: record
    cloud_data: record
    error_exit: bool
]: nothing -> record {
    aws_get_item_for_server $server $settings $cloud_data
}

export def get_infra_price [
    server: record
    data: record
    key: string
    error_exit: bool
    price_col?: string
]: nothing -> float {
    if ($data | get -o item | is-empty) { return 0.0 }
    aws_get_price $data $key $price_col
}

# Cache operations
export def start_cache_info [
    settings: record
    server: record
]: nothing -> nothing {
    aws_start_cache_info $settings $server
}

export def create_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    aws_create_cache $settings $server $error_exit
}

export def read_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    aws_read_cache $settings $server $error_exit
}

export def clean_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    aws_clean_cache $settings $server $error_exit
}

export def ip_from_cache [
    settings: record
    server: record
    error_exit: bool
]: nothing -> nothing {
    aws_ip_from_cache $settings $server $error_exit
}

# Provider metadata operations
export def on_prov_server [
    server: record
]: nothing -> string {
    aws_on_prov_server $server
}

# AWS-specific extensions (beyond standard interface)
export def create_private_network [
    settings: record
    server: record
    check: bool
]: nothing -> record {
    aws_create_private_network $settings $server $check
}

export def get_ssh_key [
    settings: record
    server: record
]: nothing -> string {
    aws_get_ssh_key $server
}

export def create_ssh_key [
    settings: record
    server: record
]: nothing -> bool {
    aws_create_ssh_key $server
}

export def make_settings [
    settings: record
    server: record
]: nothing -> record {
    aws_make_settings $settings $server
}

export def delete_settings [
    settings: record
    server: record
]: nothing -> nothing {
    aws_delete_settings $settings $server
}

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