#!/bin/bash

# Per-app "tools" dispatcher.
#
# Each container/<app>/<app>.sh that exposes Tools-tab actions defines a
# function named `<app>Tool` (e.g. `gluetunTool`) that takes two args:
#   $1 = tool id (matches an entry in <app>/<app>.tools.json)
#   $2 = pipe-encoded args string from the modal, e.g. "duration=5|mode=fast"
#
# Tool args parsing helper: see toolArgsGet below.

dockerAppRunTool()
{
    local app_name="$1"
    local tool_name="$2"
    local tool_args="$3"

    # One-file-per-tool convention: tool id `<verb>_<noun>` resolves to
    # function `app<AppName><PascalCaseToolId>`. Each tool lives at
    # containers/<app>/tools/<app>_<tool_id>.sh (live-sourced by the container scan).
    #
    # Examples:
    #   gluetun + refresh_providers     → appGluetunRefreshProviders
    #   nextcloud + reset_password      → appNextcloudResetPassword
    local app_name_ucfirst="$(tr '[:lower:]' '[:upper:]' <<< ${app_name:0:1})${app_name:1}"

    local tool_pascal=""
    local _word
    local IFS='_'
    for _word in $tool_name; do
        tool_pascal+="$(tr '[:lower:]' '[:upper:]' <<< ${_word:0:1})${_word:1}"
    done
    unset IFS

    local toolFuncName="app${app_name_ucfirst}${tool_pascal}"

    if ! declare -f "$toolFuncName" >/dev/null 2>&1; then
        isError "App '$app_name' has no tool '$tool_name' (missing function $toolFuncName — expected in containers/$app_name/tools/${app_name}_${tool_name}.sh)."
        return 1
    fi

    initializeAppVariables "$app_name"

    isHeader "Running tool '$tool_name' for $app_name"
    "$toolFuncName" "$tool_args"
    local tool_rc=$?

    # Refresh apps.json so the WebUI sees any CFG_* the tool just wrote.
    # Targeted patch (jq) instead of full regen — ~30x faster.
    if declare -F webuiPatchAppConfigJson >/dev/null 2>&1; then
        webuiPatchAppConfigJson "$app_name" >/dev/null 2>&1 || true
    elif declare -F webuiGenerateLibrePortalConfig >/dev/null 2>&1; then
        webuiGenerateLibrePortalConfig >/dev/null 2>&1 || true
    fi
    return $tool_rc
}

# Read a single value out of the pipe-encoded args string. Usage:
#   local val
#   val=$(toolArgsGet "$tool_args" "duration")
toolArgsGet()
{
    local args="$1"
    local key="$2"
    local pair value
    IFS='|' read -ra _pairs <<< "$args"
    for pair in "${_pairs[@]}"; do
        if [[ "$pair" == "$key="* ]]; then
            value="${pair#${key}=}"
            printf '%s' "$value"
            return 0
        fi
    done
    return 1
}
