#!/bin/bash

dockerUninstallApp()
{
    local app_name="$1"
    # Optional: delete the app's docker images too. Default false so a
    # plain `libreportal app uninstall <app>` keeps cached images for a
    # quick reinstall. The WebUI's Uninstall modal exposes this as the
    # "Also delete docker image" checkbox.
    local delete_images="${2:-false}"
    local delete_tasks="${3:-false}"
    local stored_app_name=$app_name

    if [[ "$stored_app_name" == "" ]]; then
        isError "No app_name provided, unable to continue..."
    else
        isHeader "Uninstalling $stored_app_name"
        initializeAppVariables $stored_app_name;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Removing app where docker compose is installed"
        echo ""

        dockerComposeDownRemove $stored_app_name;

        # App-specific uninstall hook. Host-installed apps (and any app needing
        # teardown beyond the generic docker/DB cleanup) define an uninstall<App>
        # function — it runs the app-specific bits (apt purge, systemd units,
        # cscli state, ...) while the shared compose/data/DB/WebUI teardown below
        # stays generic. The CLI and menu both route uninstalls through here, so
        # this is the single point every uninstall passes through.
        local app_name_ucfirst="$(tr '[:lower:]' '[:upper:]' <<< ${stored_app_name:0:1})${stored_app_name:1}"
        local uninstallFuncName="uninstall${app_name_ucfirst}"
        if declare -f "$uninstallFuncName" >/dev/null 2>&1; then
            ((menu_number++))
            echo ""
            echo "---- $menu_number. Running $stored_app_name-specific uninstall steps"
            echo ""
            "$uninstallFuncName"
        fi

        ((menu_number++))
        echo ""
        if [[ "$delete_images" == "true" ]]; then
            echo "---- $menu_number. Removing Docker images for the app"
            echo ""
            dockerRemoveAppImages $stored_app_name;
        else
            echo "---- $menu_number. Keeping Docker images (pass --delete-images to remove)"
            echo ""
            isNotice "Docker images for '$stored_app_name' left in place. A reinstall will reuse them."
        fi

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Deleting all app data from docker folder"
        echo ""

        dockerDeleteData $stored_app_name;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Removing unused Docker networks."
        echo ""

        dockerPruneAppNetworks $stored_app_name;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Removing app from the database"
        echo ""

        ipRemoveFromDatabase $stored_app_name;
        portsRemoveFromDatabase $stored_app_name;
        databaseUninstallApp $stored_app_name;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Updating the WebUI config file."
        echo ""

        webuiContainerSetup $stored_app_name uninstall;

        # A removed app may have been routed through a network gateway (e.g.
        # gluetun); let each provider refresh its forwarded-port registration.
        # Each hook self-skips when its provider isn't installed.
        local _np_fn
        for _np_fn in $(compgen -A function 2>/dev/null | grep '^appNetworkRegisterPorts_'); do
            "$_np_fn"
        done

        if [[ "$delete_tasks" == "true" ]]; then
            ((menu_number++))
            echo ""
            echo "---- $menu_number. Removing related task history"
            echo ""
            local _tasks_dir="${containers_dir}libreportal/frontend/data/tasks"
            local _removed=0
            if [[ -d "$_tasks_dir" ]]; then
                for _tf in "$_tasks_dir"/task_*.json; do
                    [[ ! -f "$_tf" ]] && continue
                    # Skip in-flight tasks — that includes the uninstall task
                    # we're currently inside, plus anything queued or running.
                    if runFileOp grep -qE "\"status\"[[:space:]]*:[[:space:]]*\"(running|queued|pending)\"" "$_tf" 2>/dev/null; then
                        continue
                    fi
                    if runFileOp grep -q "\"app\"[[:space:]]*:[[:space:]]*\"${stored_app_name}\"" "$_tf" 2>/dev/null; then
                        local _id=$(basename "$_tf" .json)
                        runFileOp rm -f "$_tf" "$_tasks_dir/${_id}.log" "$_tasks_dir/${_id}.cancel" 2>/dev/null
                        _removed=$((_removed + 1))
                    fi
                done
            fi
            isSuccessful "Removed $_removed task record(s) for $stored_app_name (in-flight task left for the WebUI to clean up after completion)."
        fi

        ((menu_number++))
        echo ""
        isSuccessful "$stored_app_name has been removed from your system!"
        echo ""
        
        menu_number=0
        cd
    fi
}
