# VM Lifecycle Commands (Phase 2)
#
# User-facing commands for permanent/temporary VM management with cleanup.
# Error handling: Result pattern (hybrid, no try-catch)

use lib_provisioning/result.nu *
use lib_provisioning/vm/ {
    "register-permanent-vm"
    "register-temporary-vm"
    "list-permanent-vms"
    "list-temporary-vms"
    "find-expired-vms"
    "cleanup-expired-vms"
    "get-vm-uptime"
    "get-vm-time-to-cleanup"
    "extend-vm-ttl"
    "recover-vms-on-boot"
    "start-cleanup-scheduler"
    "stop-cleanup-scheduler"
    "get-cleanup-scheduler-status"
    "get-cleanup-queue"
    "create-vm-recovery-script"
}

export def "vm list-permanent" []: table {
    """
    List all permanent VMs.

    Permanent VMs persist across reboots and host shutdowns.

    Examples:
        provisioning vm list-permanent
    """

    let permanent = (list-permanent-vms)

    if ($permanent | length) == 0 {
        print "No permanent VMs registered"
        return []
    }

    $permanent
    | map {|vm|
        {
            name: $vm.vm_name
            created: $vm.created_at
            auto_start: ($vm.auto_start // false)
            restart_policy: ($vm.restart_policy // "always")
        }
    }
}

export def "vm list-temporary" []: table {
    """
    List all temporary VMs.

    Temporary VMs are automatically cleaned up after TTL expires.

    Examples:
        provisioning vm list-temporary
    """

    let temporary = (list-temporary-vms)

    if ($temporary | length) == 0 {
        print "No temporary VMs registered"
        return []
    }

    $temporary
    | map {|vm|
        let time_info = (get-vm-time-to-cleanup $vm.vm_name)

        {
            name: $vm.vm_name
            ttl_hours: $vm.ttl_hours
            created: $vm.created_at
            scheduled_cleanup: $vm.scheduled_cleanup_at
            status: $vm.cleanup_status
            time_remaining: ($time_info.time_remaining_formatted // "expired")
        }
    }
}

export def "vm make-permanent" [
    name: string                  # VM name
    --auto-start = true           # Auto-start on boot
]: table {
    """
    Convert temporary VM to permanent.

    Cancels scheduled cleanup and registers for autostart.

    Examples:
        provisioning vm make-permanent test-vm
    """

    let result = (register-permanent-vm {name: $name, permanent: true})

    if $result.success {
        print $"✓ VM '($name)' registered as permanent"
        print $"  Auto-start: ($auto_start)"
    } else {
        print $"✗ Failed: ($result.error)"
    }

    [$result]
}

export def "vm make-temporary" [
    name: string                  # VM name
    --ttl-hours: int = 24         # Time to live
]: table {
    """
    Convert permanent VM to temporary.

    Schedules automatic cleanup after TTL.

    Examples:
        provisioning vm make-temporary dev-vm --ttl-hours 48
    """

    let result = (register-temporary-vm {name: $name, temporary: true} $ttl_hours)

    if $result.success {
        print $"✓ VM '($name)' registered as temporary"
        print $"  TTL: ($ttl_hours) hours"
        print $"  Cleanup scheduled at: ($result.cleanup_scheduled_at)"
    } else {
        print $"✗ Failed: ($result.error)"
    }

    [$result]
}

export def "vm info-lifecycle" [
    name: string                  # VM name
]: record {
    """
    Get lifecycle information for a VM.

    Shows persistence mode, uptime, cleanup schedule, etc.

    Examples:
        provisioning vm info-lifecycle dev-rust
    """

    # Guard: Input validation
    if ($name | is-empty) {
        print "Error: VM name is required"
        return {}
    }

    let uptime = (get-vm-uptime $name)

    # Guard: Optional cleanup info (may not exist for permanent VMs)
    # Using optional operator instead of try-catch
    let time_to_cleanup = (try-wrap {
        get-vm-time-to-cleanup $name
    } | unwrap-or {error: "Not a temporary VM"})

    {
        vm_name: $name
        uptime: $uptime
        cleanup_info: $time_to_cleanup
    }
}

export def "vm cleanup-now" [
    --dry-run = false             # Simulate without deleting
    --force = false               # Force shutdown before cleanup
]: table {
    """
    Cleanup expired temporary VMs now.

    Immediately deletes VMs that have exceeded their TTL.

    Examples:
        # Dry-run (show what would be deleted)
        provisioning vm cleanup-now --dry-run

        # Force cleanup
        provisioning vm cleanup-now --force
    """

    let result = (cleanup-expired-vms --dry-run=$dry_run --force=$force)

    if $result.cleaned_up > 0 {
        print $"✓ Cleaned up ($result.cleaned_up) VMs"
    } else if $dry_run {
        print "No VMs pending cleanup"
    }

    print $"Total processed: ($result.total_expired)"
    print $"Successful: ($result.cleaned_up)"
    print $"Failed: ($result.failed)"

    $result.details
}

export def "vm extend-ttl" [
    name: string                  # VM name
    hours: int                    # Hours to add
]: table {
    """
    Extend TTL for a temporary VM.

    Delays cleanup by adding more hours to the original TTL.

    Examples:
        provisioning vm extend-ttl test-vm 24    # Add 24 hours
        provisioning vm extend-ttl test-vm 72    # Add 3 days
    """

    # Guards: Input validation
    if ($name | is-empty) {
        print "Error: VM name is required"
        return [{success: false, error: "VM name is required"}]
    }
    if $hours <= 0 {
        print "Error: Hours must be positive"
        return [{success: false, error: "Hours must be positive"}]
    }

    # Main operation: Use try-wrap to convert exceptions to Result
    let result = (
        use lib_provisioning/vm/vm_persistence.nu extend-vm-ttl
        try-wrap {
            extend-vm-ttl $name $hours
        }
    )

    # Handle result explicitly
    if (is-ok $result) {
        let extended = $result.ok
        print $"✓ Extended TTL for '($name)' by ($hours) hours"
        let new_cleanup = (try-wrap { get-vm-time-to-cleanup $name } | unwrap-or {time_remaining_formatted: "unknown"})
        print $"  New cleanup time: ($new_cleanup.time_remaining_formatted)"
        [{success: true, error: null} | merge $extended]
    } else {
        print $"✗ Failed: ($result.err)"
        [{success: false, error: $result.err}]
    }
}

export def "vm scheduler start" [
    --interval-minutes: int = 60  # Check interval
]: table {
    """
    Start automatic cleanup scheduler.

    Runs in background and periodically cleans up expired VMs.

    Examples:
        provisioning vm scheduler start
        provisioning vm scheduler start --interval-minutes 30
    """

    let result = (start-cleanup-scheduler --check-interval-minutes=$interval_minutes --background)

    if $result.success {
        print $"✓ Cleanup scheduler started (PID: ($result.pid))"
        print $"  Check interval: ($interval_minutes) minutes"
    } else {
        print $"✗ Failed: ($result.error)"
    }

    [$result]
}

export def "vm scheduler stop" []: table {
    """
    Stop automatic cleanup scheduler.

    Examples:
        provisioning vm scheduler stop
    """

    # Main operation: Use try-wrap to convert exceptions to Result
    let result = (
        use lib_provisioning/vm/cleanup_scheduler.nu stop-cleanup-scheduler
        try-wrap {
            stop-cleanup-scheduler
        }
    )

    # Handle result explicitly
    if (is-ok $result) {
        print $"✓ Cleanup scheduler stopped"
        [{success: true, error: null}]
    } else {
        print $"✗ Failed: ($result.err)"
        [{success: false, error: $result.err}]
    }

    [$result]
}

export def "vm scheduler status" []: record {
    """
    Check cleanup scheduler status.

    Examples:
        provisioning vm scheduler status
    """

    get-cleanup-scheduler-status
}

export def "vm cleanup-queue" []: table {
    """
    Show VMs pending cleanup.

    Examples:
        provisioning vm cleanup-queue
    """

    let queue = (get-cleanup-queue)

    if ($queue | length) == 0 {
        print "No VMs pending cleanup"
        return []
    }

    print $"($queue | length) VMs pending cleanup:"
    $queue
}

export def "vm recovery-enable" []: table {
    """
    Enable VM recovery on system reboot.

    Creates systemd service for automatic VM recovery.

    Examples:
        provisioning vm recovery-enable
    """

    let result = (create-vm-recovery-script)

    if $result.success {
        print $"✓ VM recovery service created"
        print $"  Script: ($result.script_path)"
        print $"  Service: ($result.service_path)"
        print "  Run 'systemctl status vm-recovery' to check status"
    } else {
        print $"✗ Failed: ($result.error)"
    }

    [$result]
}

export def "vm lifecycle-stats" []: record {
    """
    Show VM lifecycle statistics.

    Examples:
        provisioning vm lifecycle-stats
    """

    use lib_provisioning/vm/vm_persistence.nu get-vm-persistence-stats

    let stats = (get-vm-persistence-stats)

    print $"Total VMs: ($stats.total_vms)"
    print $"  Permanent: ($stats.permanent_vms)"
    print $"  Temporary: ($stats.temporary_vms)"
    print $"  Expired: ($stats.expired_vms)"
    print $"  Auto-cleanup enabled: ($stats.auto_cleanup_enabled)"

    $stats
}
