# Workspace Documentation Generator
# Generates deployment, configuration, and troubleshooting guides from Jinja2 templates
# Uses workspace metadata to populate guide variables

use ../utils/nickel_processor.nu [ncl-eval]

def extract-workspace-metadata [workspace_path: string] {
    {
        workspace_path: $workspace_path,
        config_path: $"($workspace_path)/config/config.ncl",
    }
}

def extract-workspace-name [metadata: record] {
    ncl-eval ($metadata.workspace_path | path join "config/config.ncl") [$metadata.workspace_path] | get workspace.name
}

def extract-provider-config [metadata: record] {
    let config = (ncl-eval ($metadata.workspace_path | path join "config/config.ncl") [$metadata.workspace_path])
    let providers = $config.providers

    let provider_names = ($providers | columns)
    let provider_list = (
        $provider_names
        | each { |name| { name: $name, enabled: (($providers | get $name).enabled) } }
    )

    let first_enabled_provider = (
        $provider_list
        | where enabled == true
        | first
        | get name
    )

    {
        name: $first_enabled_provider,
        enabled: true
    }
}

def extract-infrastructures [workspace_path: string] {
    let infra_dir = $"($workspace_path)/infra"

    if ($infra_dir | path exists) {
        ls $infra_dir
        | where type == dir
        | get name
        | each { |path| $path | path basename }
    } else {
        []
    }
}

def extract-servers [workspace_path: string, infra: string] {
    let servers_file = $"($workspace_path)/infra/($infra)/servers.ncl"

    if ($servers_file | path exists) {
        let exported = (ncl-eval $servers_file [$workspace_path])
        $exported.servers
    } else {
        []
    }
}

def extract-taskservs [workspace_path: string, infra: string] {
    let taskservs_dir = $"($workspace_path)/infra/($infra)/taskservs"

    if ($taskservs_dir | path exists) {
        ls $taskservs_dir
        | where name ends-with .ncl
        | get name
        | each { |path| $path | path basename | str replace --regex '\.ncl$' '' }
    } else {
        []
    }
}

def generate-guide [template_path: string, output_path: string, variables: record] {
    let output_dir = ($output_path | path dirname)

    if not ($output_dir | path exists) {
        mkdir $output_dir
    }

    let rendered = (tera-render $template_path $variables)
    $rendered | save --force $output_path
}

export def generate-all-guides [workspace_path: string, template_dir: string, output_dir: string] {
    let metadata = (extract-workspace-metadata $workspace_path)
    let workspace_name = (extract-workspace-name $metadata)
    let provider_info = (extract-provider-config $metadata)
    let all_infra = (extract-infrastructures $workspace_path)
    # Filter out library/technical directories
    let infrastructures = ($all_infra | where $it != "lib")

    let default_infra = if ($infrastructures | is-empty) {
        "default"
    } else {
        $infrastructures | first
    }

    let extracted_servers = (extract-servers $workspace_path $default_infra)
    let taskservs = (extract-taskservs $workspace_path $default_infra)

    # Map server fields to template-friendly names
    let servers = (
        $extracted_servers
        | each { |srv|
            let stg = if (($srv.storages | length) > 0) {
                ($srv.storages | get 0).total
            } else {
                0
            }
            { name: $srv.hostname, plan: $srv.plan, storage: $stg, provider: $srv.provider, zone: $srv.zone }
        }
    )

    let variables = {
        workspace_name: $workspace_name,
        workspace_path: $workspace_path,
        workspace_description: "Workspace infrastructure deployment",
        primary_provider: $provider_info.name,
        primary_zone: "es-mad1",
        alternate_zone: "nl-ams1",
        default_infra: $default_infra,
        providers: [$provider_info.name],
        infrastructures: $infrastructures,
        servers: $servers,
        taskservs: $taskservs,
        pricing_estimate: "€30-40/month",
        provider_url: "https://hub.upcloud.com",
        provider_api_url: "https://upcloud.com/api/",
        provider_api_host: "api.upcloud.com",
        provider_status_url: "https://status.upcloud.com",
        provider_env_vars: {
            "UPCLOUD_USER": "username",
            "UPCLOUD_PASSWORD": "password",
        },
        provider_defaults: {
            "api_timeout": "30",
        },
        provider_zone_defaults: {
            "zone": "es-mad1",
            "plan": "2xCPU-4GB",
        },
        infrastructure_purposes: {
            "wuji": "Kubernetes cluster for production workloads",
            "sgoyol": "Development and testing environment",
        },
        server_plans: [
            "1xCPU-1GB",
            "1xCPU-2GB",
            "2xCPU-4GB",
            "2xCPU-8GB",
            "4xCPU-8GB",
            "4xCPU-16GB",
        ],
        available_zones: [
            "us-east-1",
            "us-west-1",
            "nl-ams1",
            "es-mad1",
            "fi-hel1",
        ],
        provider_config_example: {
            "username": "your-username",
            "password": "your-password",
            "default-zone": "es-mad1",
        },
    }

    print $"Generating guides for workspace: ($workspace_name)"

    let guides = [
        {
            template: "deployment-guide.md.j2",
            output: "deployment-guide.md",
        },
        {
            template: "configuration-guide.md.j2",
            output: "configuration-guide.md",
        },
        {
            template: "troubleshooting.md.j2",
            output: "troubleshooting.md",
        },
        {
            template: "README.md.j2",
            output: "README.md",
        },
    ]

    $guides
    | each { |guide|
        let template_path = $"($template_dir)/($guide.template)"
        let output_path = $"($output_dir)/($guide.output)"

        print $"  Generating ($guide.output)..."

        generate-guide $template_path $output_path $variables
    }

    print "Documentation generation complete!"
}

def main [workspace_path: string] {
    # Get absolute paths - resolve from project root
    let current_dir = (pwd)
    let abs_workspace_path = (($workspace_path | path expand) | if (($in | path type) == relative) { ($"($current_dir)/($in)") } else { $in })
    let template_dir = ($"($current_dir)/provisioning/templates/docs" | path expand)
    let output_dir = ($"($abs_workspace_path)/docs" | path expand)

    if not ($template_dir | path exists) {
        print $"Template directory not found at ($template_dir)"
    } else {
        generate-all-guides $abs_workspace_path $template_dir $output_dir
    }
}
