#!/bin/bash

# Patch one app's .config entry in apps.json without re-emitting the
# whole file. Roughly 30x faster than webuiGenerateLibrePortalConfig
# for the common "tool mutated one CFG_*" case.
webuiPatchAppConfigJson() {
    local app_name="$1"
    [[ -z "$app_name" ]] && return 1

    local apps_json="${containers_dir}libreportal/frontend/data/apps/generated/apps.json"
    [[ ! -f "$apps_json" ]] && return 1

    local deployed_cfg="${containers_dir}${app_name}/${app_name}.config"
    local install_cfg="${install_containers_dir}/${app_name}/${app_name}.config"
    local cfg_file
    if [[ -f "$deployed_cfg" ]]; then cfg_file="$deployed_cfg"
    elif [[ -f "$install_cfg" ]]; then cfg_file="$install_cfg"
    else return 1
    fi

    if ! command -v jq >/dev/null 2>&1; then
        webuiGenerateLibrePortalConfig >/dev/null 2>&1 || true
        return 0
    fi

    # Build a JSON object of every CFG_<APP>_* assignment in the file.
    local cfg_json
    cfg_json=$(awk -F= '
        /^[[:space:]]*#/ { next }
        /^[[:space:]]*$/ { next }
        $1 ~ /^CFG_[A-Z0-9_]+$/ {
            key = $1
            val = substr($0, index($0, "=") + 1)
            sub(/[[:space:]]*#.*$/, "", val)
            sub(/[[:space:]]+$/, "", val)
            if (val ~ /^".*"$/) val = substr(val, 2, length(val) - 2)
            gsub(/\\/, "\\\\", val); gsub(/"/, "\\\"", val)
            gsub(/\t/, "\\t", val); gsub(/\r/, "\\r", val); gsub(/\n/, "\\n", val)
            entries[++n] = "\"" key "\":\"" val "\""
        }
        END {
            out = "{"
            for (i = 1; i <= n; i++) { if (i > 1) out = out ","; out = out entries[i] }
            print out "}"
        }
    ' "$cfg_file")

    # Pull installed status from the apps DB so install/uninstall flips it.
    local installed="false"
    if [[ -f "$docker_dir/$db_file" ]]; then
        local row
        row=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT status FROM apps WHERE name = '${app_name//\'/\'\'}';" 2>/dev/null)
        [[ "$row" == "1" ]] && installed="true"
    fi

    local tmp="$(mktemp)"
    if jq --arg slug "$app_name" --argjson cfg "$cfg_json" --argjson inst "$installed" '
        .apps |= map(if ((.command // "") | endswith(" " + $slug)) then .config = $cfg | .installed = $inst else . end)
    ' "$apps_json" > "$tmp" 2>/dev/null; then
        runFileWrite "$apps_json" < "$tmp"; rm -f "$tmp"
        runFileOp chown "$docker_install_user:$docker_install_user" "$apps_json" 2>/dev/null || true
        return 0
    fi
    rm -f "$tmp"
    webuiGenerateLibrePortalConfig >/dev/null 2>&1 || true
}
