# Module: Installer Metadata Analysis
# Purpose: Analyzes distribution structure, components, versions, and installation requirements
# Dependencies: None (standalone utilities)

# Extract distribution archive for analysis
export def extract_distribution_for_analysis [dist_path: string, installer_config: record] {
    let temp_dir = ($installer_config.output_dir | path join "tmp" "analysis")
    mkdir $temp_dir

    let dist_name = ($dist_path | path basename)

    if ($dist_name | str ends-with ".tar.gz") or ($dist_name | str ends-with ".tgz") {
        cd $temp_dir
        tar -xzf $dist_path
    } else if ($dist_name | str ends-with ".zip") {
        cd $temp_dir
        unzip $dist_path
    } else {
        return { status: "error", reason: $"Unsupported archive format: ($dist_name)" }
    }

    # Find the extracted directory (usually a single top-level directory)
    let extracted_contents = (ls $temp_dir)
    if ($extracted_contents | length) == 1 and (($extracted_contents | get 0.type) == "dir") {
        return ($extracted_contents | get 0.name)
    } else {
        return $temp_dir
    }
}

# Analyze distribution components
export def analyze_distribution_components [analysis_path: string] {
    let components = {
        has_platform: (($analysis_path | path join "platform") | path exists)
        has_core: (($analysis_path | path join "core") | path exists)
        has_config: (($analysis_path | path join "config") | path exists)
        has_docs: (($analysis_path | path join "docs") | path exists)
        has_services: (($analysis_path | path join "services") | path exists)
    }

    # Find executables
    let executables = if $components.has_platform {
        ls ($analysis_path | path join "platform") | where type == file | get name
    } else if $components.has_core and (($analysis_path | path join "core" "bin") | path exists) {
        ls ($analysis_path | path join "core" "bin") | where type == file | get name
    } else {
        []
    }

    # Find configuration files
    let config_files = if $components.has_config {
        ls -la ($analysis_path | path join "config")
            | where name =~ "\\.(toml|yaml|json)$"
            | get name
    } else {
        []
    }

    # Find service definitions
    let service_files = if $components.has_services {
        ls -la ($analysis_path | path join "services")
            | where name =~ "\\.(service|yml|yaml)$"
            | get name
    } else {
        []
    }

    let components = ($components
        | insert executables $executables
        | insert config_files $config_files
        | insert service_files $service_files
        | insert total_size (get_directory_size $analysis_path))

    return $components
}

# Detect distribution version
export def detect_distribution_version [analysis_path: string] {
    # Try to find version from metadata
    let metadata_files = [
        ($analysis_path | path join "core-metadata.json")
        ($analysis_path | path join "platform-metadata.json")
        ($analysis_path | path join "metadata.json")
        ($analysis_path | path join "VERSION")
    ]

    for metadata_file in $metadata_files {
        if ($metadata_file | path exists) {
            let version = if ($metadata_file | str ends-with ".json") {
                let data = (open $metadata_file)
                $data.version? | default "unknown"
            } else {
                open $metadata_file --raw | str trim
            }

            if $version != "unknown" {
                return { version: $version, source: ($metadata_file | path basename) }
            }
        }
    }

    # Fallback: try to extract from directory name
    let dir_name = ($analysis_path | path basename)
    let version_match = ($dir_name | parse --regex ".*-([0-9]+\\.[0-9]+\\.[0-9]+)")

    if ($version_match | length) > 0 {
        return { version: ($version_match | get 0.capture0), source: "directory_name" }
    }

    return { version: "unknown", source: "none" }
}

# Analyze installation requirements
export def analyze_installation_requirements [analysis_path: string, components: record] {
    mut requirements = {
        system_user: "provisioning"
        system_group: "provisioning"
        install_dirs: []
        config_dirs: []
        data_dirs: []
        log_dirs: []
        service_dependencies: []
        port_requirements: []
    }

    # Standard installation directories
    if $components.has_platform or ($components.executables | length) > 0 {
        $requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/bin")
    }

    if $components.has_core {
        $requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/lib/provisioning")
    }

    if $components.has_config {
        $requirements.config_dirs = ($requirements.config_dirs | append "/etc/provisioning")
    }

    # Data and log directories
    $requirements.data_dirs = ($requirements.data_dirs | append "/var/lib/provisioning")
    $requirements.log_dirs = ($requirements.log_dirs | append "/var/log/provisioning")

    # Service dependencies (would analyze service files to determine)
    if $components.has_services {
        $requirements.service_dependencies = ($requirements.service_dependencies | append "network.target")
    }

    # Port requirements (would analyze configuration to determine)
    $requirements.port_requirements = ($requirements.port_requirements | append { port: 8080, description: "Main API" })

    return $requirements
}

# Get directory size helper
def get_directory_size [dir: string] {
    if not ($dir | path exists) {
        return 0
    }

    glob $"($dir)/**/*"
        | each {|file| stat $file | get size }
        | math sum
}
