#!/bin/bash

# Generate data/backup/generated/migrate.json — drives the WebUI's "Migrate"
# tab. One pass per enabled backup location: list every (source_host, app) pair
# with snapshot count + latest id/date, plus a single destination summary so
# the frontend can compute collisions and disk warnings without a per-row API
# round-trip.
#
# Triggered from webuiLibrePortalUpdate (the regen-webui pipeline). Safe to
# call ad-hoc — pure read-only restic snapshot queries; no live state changes.

webuiGenerateBackupMigrate()
{
    local output_dir="$containers_dir/libreportal/frontend/data/backup/generated"
    local output_file="$output_dir/migrate.json"
    local temp_file="${output_file}.tmp.$$"

    runFileOp mkdir -p "$output_dir"

    local generated_at
    generated_at=$(date -Iseconds)

    # --- Destination summary -------------------------------------------------
    local this_host="${CFG_INSTALL_NAME:-$(hostname)}"

    local disk_free_kb
    disk_free_kb=$(df -Pk "$containers_dir" 2>/dev/null | awk 'NR==2 {print $4}')
    [[ -z "$disk_free_kb" ]] && disk_free_kb=0

    local installed_apps_json="[" installed_first=true
    local running_apps_json="[]"
    local running_raw=""
    if command -v docker >/dev/null 2>&1; then
        running_raw=$(dockerCommandRun "docker ps --format '{{.Names}}' 2>/dev/null" 2>/dev/null)
    fi
    local running_first=true
    running_apps_json="["
    local app_dir app_slug
    for app_dir in "$containers_dir"*/; do
        [[ -d "$app_dir" ]] || continue
        app_slug=$(basename "$app_dir")
        [[ -f "${app_dir}docker-compose.yml" || -f "${app_dir}compose.yml" ]] || continue
        $installed_first || installed_apps_json+=","
        installed_first=false
        installed_apps_json+="\"$app_slug\""
        if echo "$running_raw" | grep -qx "$app_slug"; then
            $running_first || running_apps_json+=","
            running_first=false
            running_apps_json+="\"$app_slug\""
        fi
    done
    installed_apps_json+="]"
    running_apps_json+="]"

    local destination_json
    destination_json="{\"hostname\":\"$this_host\",\"disk_free_kb\":$disk_free_kb,\"installed_apps\":$installed_apps_json,\"running_apps\":$running_apps_json}"

    # --- Per-location host/app inventory -------------------------------------
    local locations_json="["
    local loc_first=true
    local idx
    while IFS= read -r idx; do
        [[ -z "$idx" ]] && continue

        local loc_name loc_uri
        loc_name=$(resticLocationName "$idx" 2>/dev/null)
        loc_uri=$(resticLocationUri "$idx" 2>/dev/null)
        local loc_name_esc loc_uri_esc
        loc_name_esc=$(printf '%s' "$loc_name" | sed 's/\\/\\\\/g; s/"/\\"/g')
        loc_uri_esc=$(printf '%s' "$loc_uri" | sed 's/\\/\\\\/g; s/"/\\"/g')

        # All snapshots in this location, one pass. Then group in shell.
        local all_json
        all_json=$(engineSnapshotsJson "$idx" 2>/dev/null)

        local hosts_json="["
        local host_first=true
        local host
        # Distinct hostnames present.
        while IFS= read -r host; do
            [[ -z "$host" ]] && continue
            # Skip our own hostname — we don't migrate to ourselves.
            [[ "$host" == "$this_host" ]] && continue

            $host_first || hosts_json+=","
            host_first=false

            local apps_json="["
            local app_first=true
            local app
            while IFS= read -r app; do
                [[ -z "$app" ]] && continue
                local app_snaps_json
                app_snaps_json=$(engineSnapshotsJson "$idx" "$app" "$host" 2>/dev/null)
                local count
                count=$(printf '%s' "$app_snaps_json" | grep -oc '"short_id":"' || echo 0)
                (( count == 0 )) && continue

                local latest_id latest_date
                latest_id=$(printf '%s' "$app_snaps_json" | grep -o '"short_id":"[^"]*"' | tail -1 | cut -d'"' -f4)
                latest_date=$(printf '%s' "$app_snaps_json" | grep -o '"time":"[^"]*"' | tail -1 | cut -d'"' -f4)

                local opt_out
                opt_out=$(migrateUrlRewriteEnabled "$app" 2>/dev/null)
                local opt_out_bool="false"
                [[ "$opt_out" == "false" ]] && opt_out_bool="true"

                $app_first || apps_json+=","
                app_first=false
                apps_json+="{\"slug\":\"$app\",\"snapshots\":$count,\"latest_id\":\"$latest_id\",\"latest_date\":\"$latest_date\",\"url_rewrite_opt_out\":$opt_out_bool}"
            done < <(printf '%s' "$all_json" | grep -o '"app=[^"]*"' | sort -u | sed 's/"app=\(.*\)"/\1/')
            apps_json+="]"

            hosts_json+="{\"hostname\":\"$host\",\"apps\":$apps_json}"
        done < <(printf '%s' "$all_json" | grep -o '"hostname":"[^"]*"' | sort -u | cut -d'"' -f4)
        hosts_json+="]"

        $loc_first || locations_json+=","
        loc_first=false
        locations_json+="{\"idx\":$idx,\"name\":\"$loc_name_esc\",\"uri\":\"$loc_uri_esc\",\"hosts\":$hosts_json}"
    done < <(resticEnabledLocations)
    locations_json+="]"

    # --- Write atomically ----------------------------------------------------
    cat > "$temp_file" <<EOF
{
  "generated_at": "$generated_at",
  "destination": $destination_json,
  "locations": $locations_json
}
EOF
    runFileOp mv "$temp_file" "$output_file"
    runFileOp chmod 644 "$output_file" 2>/dev/null || true
}
