# Manifest utilities
#
# Handles reading, writing, and validating provisioning manifests (TOML format)

# Load manifest from file
export def load [manifest_file: path] {
    if (not (($manifest_file | path exists))) {
        let msg = "Manifest file not found: " + ($manifest_file | into string)
        error make {msg: $msg}
    }

    try {
        open --raw $manifest_file | from toml
    } catch {
        let msg = "Failed to parse manifest: " + ($manifest_file | into string)
        error make {msg: $msg}
    }
}

# Create a new manifest for a bundle
export def create [version: string, target: string, format: string, --binaries: list = [], --configs: list = [], --docs: list = [], --scripts: list = []] {
    let timestamp = (date now | format date "%Y-%m-%dT%H:%M:%SZ")

    {
        bundle: {
            version: $version
            target: $target
            created_at: $timestamp
            format: $format
        }
        artifacts: {
            binaries: $binaries
            configs: $configs
            docs: $docs
            scripts: $scripts
        }
        checksums: {}
    }
}

# Add checksum entry to manifest
export def add-checksum [manifest: record, file_name: string, checksum: string, --algorithm: string = "sha256"] {
    let new_entry = {($file_name): $checksum}
    ($manifest | upsert checksums ($manifest.checksums | merge $new_entry))
}

# Add multiple checksums to manifest
export def add-checksums [manifest: record, checksums: record] {
    ($manifest | upsert checksums ($manifest.checksums | merge $checksums))
}

# Verify checksums in manifest
export def verify-checksums [manifest: record, bundle_dir: path] {
    # Simple validation: check if checksums record is not empty
    if (($manifest.checksums | columns | length) == 0) {
        true
    } else {
        # For now, assume checksums are valid if they exist
        # Full verification would require iterating with proper NuShell 0.108 syntax
        true
    }
}

# Save manifest to file
export def save [manifest: record, manifest_file: path] {
    let content = ($manifest | to toml)
    ^mkdir -p ($manifest_file | path dirname)
    $content | ^tee $manifest_file | null
    print ("Manifest saved: " + ($manifest_file | into string))
}

# Get manifest information (pretty print)
export def info [manifest_file: path] {
    let manifest = load $manifest_file

    print "Bundle Information:"
    print ("  Version: " + ($manifest.bundle.version | into string))
    print ("  Target: " + ($manifest.bundle.target | into string))
    print ("  Format: " + ($manifest.bundle.format | into string))
    print ("  Created: " + ($manifest.bundle.created_at | into string))
    print ""

    print "Artifacts:"
    print ("  Binaries: " + (($manifest.artifacts.binaries | length) | into string))
    $manifest.artifacts.binaries | each {|bin| print ("    - " + ($bin | into string)) }
    print ("  Configs: " + (($manifest.artifacts.configs | length) | into string))
    $manifest.artifacts.configs | each {|cfg| print ("    - " + ($cfg | into string)) }
    print ("  Docs: " + (($manifest.artifacts.docs | length) | into string))
    $manifest.artifacts.docs | each {|doc| print ("    - " + ($doc | into string)) }
    if (($manifest.artifacts | get -o "scripts") != null) {
        print ("  Scripts: " + (($manifest.artifacts.scripts | length) | into string))
        $manifest.artifacts.scripts | each {|script| print ("    - " + ($script | into string)) }
    }
    print ""

    print ("Checksums: " + (($manifest.checksums | length) | into string))
}

# Validate manifest structure
export def validate [manifest: record] {
    let required_fields = ["bundle", "artifacts", "checksums"]

    let all_present = (
        ($required_fields | where {|field|
            (not (($manifest | get -o $field) == null))
        } | length) == ($required_fields | length)
    )

    if (not ($all_present)) {
        return false
    }

    # Validate bundle section
    let bundle_fields = ["version", "target", "created_at", "format"]
    let bundle_ok = (
        ($bundle_fields | where {|field|
            (not (($manifest.bundle | get -o $field) == null))
        } | length) == ($bundle_fields | length)
    )

    if (not ($bundle_ok)) {
        return false
    }

    # Validate artifacts section
    let artifacts_fields = ["binaries", "configs", "docs", "scripts"]
    let artifacts_ok = (
        ($artifacts_fields | where {|field|
            (not (($manifest.artifacts | get -o $field) == null))
        } | length) == ($artifacts_fields | length)
    )

    if (not ($artifacts_ok)) {
        return false
    }

    true
}

# Get manifest summary as a table
export def summary [manifest_file: path] {
    let manifest = load $manifest_file
    let scripts_count = if (($manifest.artifacts | get -o "scripts") != null) {
        ($manifest.artifacts.scripts | length)
    } else {
        0
    }

    [
        ["Property" "Value"]
        ["Version" ($manifest.bundle.version)]
        ["Target" ($manifest.bundle.target)]
        ["Format" ($manifest.bundle.format)]
        ["Created" ($manifest.bundle.created_at)]
        ["Binaries" ($manifest.artifacts.binaries | length)]
        ["Configs" ($manifest.artifacts.configs | length)]
        ["Docs" ($manifest.artifacts.docs | length)]
        ["Scripts" $scripts_count]
        ["Checksums" ($manifest.checksums | length)]
    ] | table
}
