#!/bin/bash

# WebUI artifact-index data generator
# ---------------------------------------------------------------------------
# Writes the read-only JSON the updater "Improvements" (hotfix) stream reads:
#   frontend/data/updater/generated/artifacts_available.json
#
# It fetches + verifies the signed artifact index (lpFetchIndex), annotates each
# artifact with `applied` (a per-id applied-record exists) and `applicable` (the
# target app is installed / system-scope), and writes ATOMICALLY: build into a
# temp, validate it, then one runFileWrite. On ANY fetch/verify failure it KEEPS
# the prior file — it must never emit broken JSON, and the WebUI degrades
# gracefully when the file is absent. Run by `libreportal updater check`.

webuiArtifactScan() {
    local out_dir="${containers_dir%/}/libreportal/frontend/data/updater/generated"
    local out="$out_dir/artifacts_available.json"
    local applied_dir="$out_dir/applied"
    runFileOp mkdir -p "$out_dir" 2>/dev/null || true

    # Lazy-loader gap: ensure the read primitives are present.
    if ! declare -F lpFetchIndex >/dev/null 2>&1; then
        source "$install_scripts_dir/source/fetch.sh" 2>/dev/null
        source "$install_scripts_dir/source/artifacts.sh" 2>/dev/null
    fi
    if ! command -v jq >/dev/null 2>&1; then
        isNotice "webuiArtifactScan: jq not available — keeping the prior artifacts_available.json."
        return 0
    fi

    local index
    if ! lpFetchIndexInto index; then
        isNotice "webuiArtifactScan: no verified index available — keeping the prior file."
        return 0
    fi
    local signed="false"; [[ "$LP_INDEX_SIGSTATE" == "verified" ]] && signed="true"
    local serial now
    serial="$(_lpJsonNum "$index" index_serial)"
    now="$(date -Iseconds 2>/dev/null || date)"

    # Applied ids = basenames of applied/*.json, as a JSON array.
    local applied_ids="[]" f
    if compgen -G "$applied_dir/*.json" >/dev/null 2>&1; then
        applied_ids="$(for f in "$applied_dir"/*.json; do basename "$f" .json; done | jq -R . | jq -cs .)"
    fi
    # Installed apps = dir names under containers_dir, for the applicable check.
    local installed="[]" d
    if [[ -d "$containers_dir" ]]; then
        installed="$(for d in "$containers_dir"/*/; do [[ -d "$d" ]] && basename "$d"; done | jq -R . | jq -cs .)"
    fi

    local tmp; tmp="$(mktemp)"
    printf '%s' "$index" | jq \
        --arg now "$now" --arg signed "$signed" --arg serial "${serial:-0}" \
        --argjson applied "$applied_ids" --argjson installed "$installed" '
        { generated_at: $now,
          signed: ($signed=="true"),
          serial: ($serial|tonumber? // 0),
          artifacts: [ .artifacts[]? | {
            id, type,
            severity: (.severity // "tweak"),
            auto: (.auto // false),
            reversible: (.reversible // true),
            title: (.title // ""),
            why: (.why // ""),
            app: (.applies_when.app // null),
            applied: (.id as $i | ($applied | index($i)) != null),
            applicable: ((.applies_when.app // null) as $a | if $a == null then true else ($installed | index($a)) != null end)
          } ] }' > "$tmp" 2>/dev/null

    if ! jq empty "$tmp" 2>/dev/null; then
        isNotice "webuiArtifactScan: generated JSON was invalid — keeping the prior file."
        rm -f "$tmp"; return 1
    fi
    runFileWrite "$out" < "$tmp"
    rm -f "$tmp"
    runFileOp chown "$docker_install_user":"$docker_install_user" "$out" 2>/dev/null || true
    isSuccessful "Artifact index refreshed (serial=${serial:-?}, signed=$signed)."
}
