# Volume Management System (Phase 4)
#
# Manages storage volumes for VMs and containers.
# Rule 1: Single purpose, Rule 5: Atomic operations

export def "volume-create" [
    name: string                                 # Volume name
    size_gb: int                                 # Size in GB
    --type: string = "local"                     # Volume type
    --mount-path: string = ""                    # Mount path
    --readonly = false                           # Read-only
]: record {
    """
    Create a storage volume for VM or container.

    Supports local, NFS, CIFS, and cloud storage types.
    """

    if ($name | is-empty) {
        return {success: false, error: "Volume name required"}
    }

    if ($size_gb < 1 or $size_gb > 1000) {
        return {success: false, error: "Size must be 1-1000 GB"}
    }

    let volume_dir = (get-volumes-directory)
    bash -c $"mkdir -p ($volume_dir)" | complete

    let volume_meta = {
        name: $name
        type: $type
        size_gb: $size_gb
        mount_path: $mount_path
        readonly: $readonly
        created_at: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
        status: "created"
        path: $"($volume_dir)/($name).img"
    }

    # Create backing file (no try-catch)
    let create_result = (do { bash -c $"qemu-img create -f qcow2 ($volume_meta.path) ($size_gb)G" } | complete)
    if $create_result.exit_code != 0 {
        return {success: false, error: $"Failed to create volume: ($create_result.stderr)"}
    }

    # Save metadata (no try-catch)
    let mkdir_result = (do { bash -c $"mkdir -p ($volume_dir)/meta" } | complete)
    if $mkdir_result.exit_code != 0 {
        return {success: false, error: $"Failed to create metadata directory: ($mkdir_result.stderr)"}
    }

    let save_result = (do { bash -c $"cat > ($volume_dir)/meta/($name).json << 'EOF'\n($volume_meta | to json)\nEOF" } | complete)
    if $save_result.exit_code != 0 {
        return {success: false, error: $"Failed to save metadata: ($save_result.stderr)"}
    }

    {
        success: true
        volume_name: $name
        volume_path: $volume_meta.path
        size_gb: $size_gb
        mount_path: $mount_path
    }
}

export def "volume-list" []: table {
    """
    List all available volumes.
    """

    let volume_dir = (get-volumes-directory)

    if (not ($volume_dir | path exists)) {
        return []
    }

    bash -c $"ls -1 ($volume_dir)/meta/*.json 2>/dev/null"
    | lines
    | each {|file|
        # Guard: Check if file can be opened and parsed as JSON (no try-catch)
        let json_result = (do { open $file | from json } | complete)
        if $json_result.exit_code == 0 {
            let meta = ($json_result.stdout)
            {
                name: $meta.name
                type: $meta.type
                size_gb: $meta.size_gb
                mount_path: $meta.mount_path
                status: $meta.status
                created: $meta.created_at
            }
        } else {
            null
        }
    }
    | compact
}

export def "volume-info" [
    name: string                                 # Volume name
]: record {
    """
    Get detailed volume information.
    """

    let volume_dir = (get-volumes-directory)
    let meta_file = $"($volume_dir)/meta/($name).json"

    if (not ($meta_file | path exists)) {
        return {success: false, error: "Volume not found"}
    }

    # Load metadata (no try-catch)
    let meta_result = (do { open $meta_file | from json } | complete)
    if $meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to load volume metadata: ($meta_result.stderr)"}
    }

    let meta = ($meta_result.stdout)
    let usage = (
        bash -c $"du -h ($meta.path) 2>/dev/null | cut -f1" | str trim
    )

    {
        success: true
        name: $meta.name
        type: $meta.type
        size_gb: $meta.size_gb
        used: $usage
        mount_path: $meta.mount_path
        readonly: $meta.readonly
        created: $meta.created_at
        status: $meta.status
    }
}

export def "volume-attach" [
    volume_name: string                         # Volume name
    vm_name: string                             # VM name
    --mount-path: string = ""                   # Mount path
]: record {
    """
    Attach volume to a VM.
    """

    let volume_dir = (get-volumes-directory)
    let meta_file = $"($volume_dir)/meta/($volume_name).json"

    if (not ($meta_file | path exists)) {
        return {success: false, error: "Volume not found"}
    }

    # Load metadata (no try-catch)
    let meta_result = (do { open $meta_file | from json } | complete)
    if $meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to load volume metadata: ($meta_result.stderr)"}
    }

    let meta = ($meta_result.stdout)
    let mount = (if ($mount_path | is-empty) {$meta.mount_path} else {$mount_path})

    # Record attachment (no try-catch)
    let attachment = {
        vm_name: $vm_name
        attached_at: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
        mount_path: $mount
    }

    let mkdir_result = (do { bash -c $"mkdir -p ($volume_dir)/attachments" } | complete)
    if $mkdir_result.exit_code != 0 {
        return {success: false, error: $"Failed to create attachments directory: ($mkdir_result.stderr)"}
    }

    let append_result = (do { bash -c $"cat >> ($volume_dir)/attachments/($volume_name).txt << 'EOF'\n($vm_name)|($mount)\nEOF" } | complete)
    if $append_result.exit_code != 0 {
        return {success: false, error: $"Failed to record attachment: ($append_result.stderr)"}
    }

    {
        success: true
        volume: $volume_name
        vm: $vm_name
        mount_path: $mount
    }
}

export def "volume-detach" [
    volume_name: string                         # Volume name
    vm_name: string                             # VM name
]: record {
    """
    Detach volume from VM.
    """

    let volume_dir = (get-volumes-directory)
    let attachments_file = $"($volume_dir)/attachments/($volume_name).txt"

    if (not ($attachments_file | path exists)) {
        return {success: false, error: "No attachments found"}
    }

    # Remove attachment entry (no try-catch)
    let detach_result = (do { bash -c $"grep -v ($vm_name) ($attachments_file) > ($attachments_file).tmp && mv ($attachments_file).tmp ($attachments_file)" } | complete)
    if $detach_result.exit_code != 0 {
        return {success: false, error: $"Failed to detach volume: ($detach_result.stderr)"}
    }

    {
        success: true
        message: $"Volume detached from VM"
    }
}

export def "volume-snapshot" [
    volume_name: string                         # Volume name
    snapshot_name: string                       # Snapshot name
    --description: string = ""                  # Description
]: record {
    """
    Create snapshot of a volume.
    """

    let volume_dir = (get-volumes-directory)
    let meta_file = $"($volume_dir)/meta/($volume_name).json"

    if (not ($meta_file | path exists)) {
        return {success: false, error: "Volume not found"}
    }

    # Load metadata (no try-catch)
    let meta_result = (do { open $meta_file | from json } | complete)
    if $meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to load volume metadata: ($meta_result.stderr)"}
    }

    let meta = ($meta_result.stdout)
    let snapshot_path = $"($volume_dir)/snapshots/($volume_name)/($snapshot_name).qcow2"

    let mkdir_result = (do { bash -c $"mkdir -p $(dirname ($snapshot_path))" } | complete)
    if $mkdir_result.exit_code != 0 {
        return {success: false, error: $"Failed to create snapshot directory: ($mkdir_result.stderr)"}
    }

    # Create snapshot (no try-catch)
    let snapshot_result = (do { bash -c $"qemu-img snapshot -c ($snapshot_name) ($meta.path)" } | complete)
    if $snapshot_result.exit_code != 0 {
        return {success: false, error: $"Failed to create snapshot: ($snapshot_result.stderr)"}
    }

    let convert_result = (do { bash -c $"qemu-img convert -f qcow2 -O qcow2 -o backing_file=($meta.path) ($snapshot_path)" } | complete)
    if $convert_result.exit_code != 0 {
        return {success: false, error: $"Failed to convert snapshot: ($convert_result.stderr)"}
    }

    # Save snapshot metadata (no try-catch)
    let snapshot_meta = {
        name: $snapshot_name
        volume: $volume_name
        path: $snapshot_path
        created_at: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
        description: $description
    }

    let meta_mkdir_result = (do { bash -c $"mkdir -p ($volume_dir)/snapshots/($volume_name)" } | complete)
    if $meta_mkdir_result.exit_code != 0 {
        return {success: false, error: $"Failed to create snapshot metadata directory: ($meta_mkdir_result.stderr)"}
    }

    let meta_save_result = (do { bash -c $"cat > ($volume_dir)/snapshots/($volume_name)/($snapshot_name).json << 'EOF'\n($snapshot_meta | to json)\nEOF" } | complete)
    if $meta_save_result.exit_code != 0 {
        return {success: false, error: $"Failed to save snapshot metadata: ($meta_save_result.stderr)"}
    }

    {
        success: true
        snapshot: $snapshot_name
        volume: $volume_name
        path: $snapshot_path
    }
}

export def "volume-restore" [
    volume_name: string                         # Volume name
    snapshot_name: string                       # Snapshot name
]: record {
    """
    Restore volume from snapshot.
    """

    let volume_dir = (get-volumes-directory)
    let snapshot_dir = $"($volume_dir)/snapshots/($volume_name)"
    let snapshot_meta_file = $"($snapshot_dir)/($snapshot_name).json"

    if (not ($snapshot_meta_file | path exists)) {
        return {success: false, error: "Snapshot not found"}
    }

    # Load snapshot metadata (no try-catch)
    let snap_result = (do { open $snapshot_meta_file | from json } | complete)
    if $snap_result.exit_code != 0 {
        return {success: false, error: $"Failed to load snapshot metadata: ($snap_result.stderr)"}
    }

    let snapshot_meta = ($snap_result.stdout)
    let meta_file = $"($volume_dir)/meta/($volume_name).json"

    # Load volume metadata (no try-catch)
    let meta_result = (do { open $meta_file | from json } | complete)
    if $meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to load volume metadata: ($meta_result.stderr)"}
    }

    let meta = ($meta_result.stdout)

    # Restore from snapshot (no try-catch)
    let restore_result = (do { bash -c $"qemu-img snapshot -a ($snapshot_name) ($meta.path)" } | complete)
    if $restore_result.exit_code != 0 {
        return {success: false, error: $"Failed to restore snapshot: ($restore_result.stderr)"}
    }

    {
        success: true
        message: $"Volume restored from snapshot"
        volume: $volume_name
        snapshot: $snapshot_name
    }
}

export def "volume-delete" [
    name: string                                 # Volume name
    --force = false                              # Force delete if in use
]: record {
    """
    Delete a volume.
    """

    let volume_dir = (get-volumes-directory)
    let meta_file = $"($volume_dir)/meta/($name).json"

    if (not ($meta_file | path exists)) {
        return {success: false, error: "Volume not found"}
    }

    # Load metadata (no try-catch)
    let meta_result = (do { open $meta_file | from json } | complete)
    if $meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to load volume metadata: ($meta_result.stderr)"}
    }

    let meta = ($meta_result.stdout)

    # Check if in use (no try-catch)
    let attachments_file = $"($volume_dir)/attachments/($name).txt"
    if (($attachments_file | path exists) and (not $force)) {
        let count_result = (do { bash -c $"wc -l < ($attachments_file)" } | complete)
        if $count_result.exit_code == 0 {
            let count = ($count_result.stdout | str trim | into int)
            return {
                success: false
                error: $"Volume in use by ($count) VM(s)"
            }
        }
    }

    # Delete files (no try-catch)
    let rm_img_result = (do { bash -c $"rm -f ($meta.path)" } | complete)
    if $rm_img_result.exit_code != 0 {
        return {success: false, error: $"Failed to delete volume image: ($rm_img_result.stderr)"}
    }

    let rm_meta_result = (do { bash -c $"rm -f ($meta_file)" } | complete)
    if $rm_meta_result.exit_code != 0 {
        return {success: false, error: $"Failed to delete metadata file: ($rm_meta_result.stderr)"}
    }

    let rm_snapshots_result = (do { bash -c $"rm -rf ($volume_dir)/snapshots/($name)" } | complete)
    if $rm_snapshots_result.exit_code != 0 {
        return {success: false, error: $"Failed to delete snapshots: ($rm_snapshots_result.stderr)"}
    }

    let rm_attachments_result = (do { bash -c $"rm -f ($attachments_file)" } | complete)
    if $rm_attachments_result.exit_code != 0 {
        return {success: false, error: $"Failed to delete attachments: ($rm_attachments_result.stderr)"}
    }

    {
        success: true
        message: $"Volume deleted"
    }
}

export def "volume-stats" []: record {
    """
    Get volume system statistics.
    """

    let volume_dir = (get-volumes-directory)
    let volumes = (volume-list)

    let total_size = (
        $volumes
        | each {|v| $v.size_gb}
        | math sum
    )

    let total_used = (
        bash -c $"du -sb ($volume_dir) 2>/dev/null | cut -f1"
        | into int
        | math round -p 2
    ) / 1024 / 1024 / 1024

    {
        total_volumes: ($volumes | length)
        total_size_gb: $total_size
        total_used_gb: $total_used
        utilization_percent: (($total_used / $total_size * 100) | math round -p 1)
    }
}

def get-volumes-directory []: string {
    """Get volumes directory path"""
    "{{paths.workspace}}/vms/volumes"
}
