#!/usr/bin/env nu

# Module: Installer Creation Orchestrator
# Purpose: Orchestrates platform-specific installer generation with analysis, creation, validation
# Dependencies: installer_metadata, installer_generator, installer_validator, installer_utilities

use std log

# Import refactored modules
use ./installer_metadata.nu *
use ./installer_generator.nu *
use ./installer_validator.nu *
use ./installer_utilities.nu *

def main [
    --distribution-path: string                 # Path to distribution to create installer for (required)
    --output-dir: string = "installers"        # Output directory for installers
    --installer-types: string = "shell,package" # Installer types: shell, package, gui, all
    --platforms: string = "linux,macos,windows" # Target platforms
    --include-services = true                  # Include service installation
    --create-uninstaller = true                # Create uninstall scripts
    --sign-packages = false                    # Sign installation packages
    --validate-installer = true                # Validate generated installers
    --compression: string = "gzip"              # Compression method for packages
    --verbose                                   # Enable verbose logging
] {

    if $distribution_path == "" {
        log error "Distribution path is required"
        exit 1
    }

    let dist_root = ($distribution_path | path expand)

    if not ($dist_root | path exists) {
        log error $"Distribution path does not exist: ($dist_root)"
        exit 1
    }

    let installer_types_list = if $installer_types == "all" {
        ["shell", "package", "gui"]
    } else {
        ($installer_types | split row "," | each { str trim })
    }

    let platforms_list = ($platforms | split row "," | each { str trim })

    let installer_config = {
        distribution_path: $dist_root
        output_dir: ($output_dir | path expand)
        installer_types: $installer_types_list
        platforms: $platforms_list
        include_services: $include_services
        create_uninstaller: $create_uninstaller
        sign_packages: $sign_packages
        validate_installer: $validate_installer
        compression: $compression
        verbose: $verbose
    }

    log info $"Starting installer creation with config: ($installer_config)"

    # Ensure output directory exists
    mkdir ($installer_config.output_dir)

    let creation_results = []

    let result = (do {
        # Phase 1: Analyze distribution
        let analysis_result = analyze_distribution $installer_config

        let creation_results = ($creation_results | append { phase: "analysis", result: $analysis_result })

        if $analysis_result.status != "success" {
            log error $"Distribution analysis failed: ($analysis_result.reason)"
            exit 1
        }

        # Phase 2: Create shell installers
        let shell_result = if "shell" in $installer_config.installer_types {
            create_shell_installers $installer_config $analysis_result
        } else {
            { status: "skipped", reason: "shell installers not requested" }
        }

        let creation_results = ($creation_results | append { phase: "shell", result: $shell_result })

        # Phase 3: Create package installers
        let package_result = if "package" in $installer_config.installer_types {
            create_package_installers $installer_config $analysis_result
        } else {
            { status: "skipped", reason: "package installers not requested" }
        }

        let creation_results = ($creation_results | append { phase: "package", result: $package_result })

        # Phase 4: Create GUI installers
        let gui_result = if "gui" in $installer_config.installer_types {
            create_gui_installers $installer_config $analysis_result
        } else {
            { status: "skipped", reason: "GUI installers not requested" }
        }

        let creation_results = ($creation_results | append { phase: "gui", result: $gui_result })

        # Phase 5: Create uninstallers
        let uninstall_result = if $installer_config.create_uninstaller {
            create_uninstall_scripts $installer_config $analysis_result
        } else {
            { status: "skipped", reason: "uninstaller creation disabled" }
        }

        let creation_results = ($creation_results | append { phase: "uninstall", result: $uninstall_result })

        # Phase 6: Validate installers
        let validation_result = if $installer_config.validate_installer {
            validate_installers $installer_config $creation_results
        } else {
            { status: "skipped", reason: "installer validation disabled" }
        }

        let creation_results = ($creation_results | append { phase: "validation", result: $validation_result })

        let summary = {
            distribution_path: $installer_config.distribution_path
            output_directory: $installer_config.output_dir
            installer_types: ($installer_config.installer_types | length)
            platforms: ($installer_config.platforms | length)
            successful_phases: ($creation_results | where {|r| $r.result.status == "success"} | length)
            total_phases: ($creation_results | length)
            installers_created: (count_created_installers $creation_results)
            installer_config: $installer_config
            phases: $creation_results
        }

        log info $"Installer creation completed - ($summary.installers_created) installers created"

        $summary
    } | complete)

    if $result.exit_code != 0 {
        log error $"Installer creation failed: ($result.stderr)"
        exit 1
    }

    $result.stdout
}

# Analysis orchestrator - coordinates metadata analysis
def analyze_distribution [installer_config: record] {
    log info "Analyzing distribution structure..."

    let start_time = (date now)

    let result = (do {
        let dist_path = $installer_config.distribution_path

        # Detect distribution type and structure
        let dist_info = {
            is_archive: (($dist_path | path type) == "file")
            is_directory: (($dist_path | path type) == "dir")
            name: ($dist_path | path basename)
        }

        # If it's an archive, we need to extract it temporarily for analysis
        let analysis_path = if $dist_info.is_archive {
            extract_distribution_for_analysis $dist_path $installer_config
        } else {
            $dist_path
        }

        # Analyze distribution contents
        let components = analyze_distribution_components $analysis_path

        # Detect version information
        let version_info = detect_distribution_version $analysis_path

        # Analyze installation requirements
        let requirements = analyze_installation_requirements $analysis_path $components

        {
            status: "success"
            distribution_info: $dist_info
            analysis_path: $analysis_path
            components: $components
            version_info: $version_info
            requirements: $requirements
            duration: ((date now) - $start_time)
        }
    } | complete)

    if $result.exit_code != 0 {
        {
            status: "failed"
            reason: $result.stderr
            duration: ((date now) - $start_time)
        }
    } else {
        $result.stdout
    }
}

# Show installer creation status
def "main status" [distribution_path: string = ""] {
    if $distribution_path == "" {
        return {
            error: "distribution path required"
            usage: "main status <distribution-path>"
            supported_platforms: ["linux", "macos", "windows"]
            installer_types: ["shell", "package", "gui"]
        }
    }

    let dist_path = ($distribution_path | path expand)

    if not ($dist_path | path exists) {
        return {
            error: "distribution path does not exist"
            path: $dist_path
        }
    }

    # Quick analysis of distribution
    let dist_info = {
        path: $dist_path
        type: ($dist_path | path type)
        name: ($dist_path | path basename)
        size: (get_directory_size $dist_path)
    }

    {
        distribution: $dist_info
        can_create_installers: true
        supported_platforms: ["linux", "macos", "windows"]
        installer_types: ["shell", "package", "gui"]
        features: {
            shell_installers: true
            package_installers: false  # Not fully implemented
            gui_installers: false      # Not fully implemented
            uninstallers: true
            service_management: true
        }
    }
}

# Quick installer creation with minimal options
def "main quick" [
    distribution_path: string                   # Distribution to create installer for
    --platform: string = "linux"               # Single platform
    --output-dir: string = "installers"        # Output directory
] {
    main $distribution_path --platforms $platform --installer-types shell --output-dir $output_dir
}
