# init-scripts.sh — SDKMAN .sdkmanrc support, init script processing, CMD_PREAMBLE build.
# shellcheck shell=bash
# Requires: _strip_crlf, die (from helpers.sh), _collect_project_files, _confirm_project_files
#           (from approval.sh).
# Exports globals: SDKMANRC_FOUND, PROJECT_INIT_APPROVED, PROJECT_INIT_COPIES,
#                  TRUSTED_INIT_COPIES, CMD_PREAMBLE (read by exec-drop.sh).
# /tmp/.devcage-approved-inits is read by devcage-session — format must not change.
# Copyright (c) 2026 Progralink. Licensed under the DevCage License — see LICENSE.

SDKMANRC_FOUND=0
PROJECT_INIT_APPROVED=0
declare -A PROJECT_INIT_COPIES=()
declare -A TRUSTED_INIT_COPIES=()
CMD_PREAMBLE=""

# _setup_sdkman: detect .sdkmanrc in /workspace and configure .bashrc accordingly.
# Sets SDKMANRC_FOUND=1 if workspace has a .sdkmanrc and SDKMAN is available.
_setup_sdkman() {
    SDKMANRC_FOUND=0
    if [ -f /workspace/.sdkmanrc ] && [ -s "${SDKMAN_DIR:-/home/devcage/.sdkman}/bin/sdkman-init.sh" ]; then
        SDKMANRC_FOUND=1
        if ! grep -qF 'sdk env install' /home/devcage/.bashrc 2>/dev/null; then
            echo 'cd /workspace && sdk env install' >> /home/devcage/.bashrc
        fi
    fi
}

# _process_init_scripts: source init scripts from /sandbox-init.d/ in hierarchical order.
# Global (01*) and user (02*) scripts are trusted. Custom (04*) are trusted.
# Project scripts (03-project.sh, 03p*) require batch confirmation.
# All approved scripts are appended to .bashrc for interactive shells.
# Writes /tmp/.devcage-approved-inits manifest (read by devcage-session).
_process_init_scripts() {
    PROJECT_INIT_APPROVED=0
    PROJECT_INIT_COPIES=()
    TRUSTED_INIT_COPIES=()

    # Remove previous init-script block from .bashrc (idempotent on container restart)
    sed -i '/^# -- devcage-init-start --$/,/^# -- devcage-init-end --$/d' /home/devcage/.bashrc 2>/dev/null || true
    echo '# -- devcage-init-start --' >> /home/devcage/.bashrc

    if [ -d /sandbox-init.d ]; then
        # First pass: collect project-scope scripts and copy them (TOCTOU protection)
        local _project_scripts=()
        _collect_project_files /sandbox-init.d "*.sh" "03-project.sh|03p*" ".sh" \
            PROJECT_INIT_COPIES _project_scripts

        # Batch confirmation for all project-scope scripts
        if [ ${#_project_scripts[@]} -gt 0 ]; then
            _confirm_project_files "init script" "Run these scripts?" \
                PROJECT_INIT_COPIES _project_scripts PROJECT_INIT_APPROVED
        fi

        # Second pass: process all scripts in order
        local _initf _initbase _clean
        for _initf in /sandbox-init.d/*.sh; do
            [ -f "$_initf" ] || continue
            _initbase="$(basename "$_initf")"
            case "$_initbase" in
                03-project.sh|03p*)
                    if [ "$PROJECT_INIT_APPROVED" = "1" ] && [ "${PROJECT_INIT_COPIES[$_initbase]:-}" != "" ]; then
                        echo ". '${PROJECT_INIT_COPIES[$_initbase]}'" >> /home/devcage/.bashrc
                    fi
                    ;;
                *)
                    # Trusted scripts (global, user, custom): sanitize and source
                    _clean="$(mktemp /tmp/.devcage-clean-XXXXXXXX.sh)"
                    TRUSTED_INIT_COPIES["$_initbase"]="$_clean"
                    sed 's/\r$//' "$_initf" > "$_clean"
                    chmod 644 "$_clean"
                    echo ". '${_clean}'" >> /home/devcage/.bashrc
                    ;;
            esac
        done

        # Write manifest of approved project init scripts for devcage-session.
        # Sort keys to match glob order (bash associative arrays are unordered).
        : > /tmp/.devcage-approved-inits
        if [ "$PROJECT_INIT_APPROVED" = "1" ]; then
            local _ps
            while IFS= read -r _ps; do
                echo "${PROJECT_INIT_COPIES[$_ps]}" >> /tmp/.devcage-approved-inits
            done < <(printf '%s\n' "${!PROJECT_INIT_COPIES[@]}" | sort)
        fi
    fi
    echo '# -- devcage-init-end --' >> /home/devcage/.bashrc
}

# _build_cmd_preamble: build CMD_PREAMBLE for non-interactive (command-mode) sessions.
# Iterates /sandbox-init.d/*.sh in the same glob order as _process_init_scripts
# so interactive and command modes see identical init state.
# CMD_PREAMBLE is read by exec-drop.sh and exported for devcage-session.
_build_cmd_preamble() {
    CMD_PREAMBLE=""
    if [ "$SDKMANRC_FOUND" = "1" ]; then
        # shellcheck disable=SC2016  # $HOME expands at execution time, not assignment
        CMD_PREAMBLE='. "$HOME/.sdkman/bin/sdkman-init.sh" && cd /workspace && sdk env install; '
    fi
    if [ -d /sandbox-init.d ]; then
        local _initf _initbase _clean
        for _initf in /sandbox-init.d/*.sh; do
            [ -f "$_initf" ] || continue
            _initbase="$(basename "$_initf")"
            case "$_initbase" in
                03-project.sh|03p*)
                    if [ "$PROJECT_INIT_APPROVED" = "1" ] && [ "${PROJECT_INIT_COPIES[$_initbase]:-}" != "" ]; then
                        CMD_PREAMBLE="${CMD_PREAMBLE}. '${PROJECT_INIT_COPIES[$_initbase]}'; "
                    fi
                    ;;
                *)
                    _clean="${TRUSTED_INIT_COPIES[$_initbase]:-}"
                    [ "$_clean" = "" ] && continue
                    CMD_PREAMBLE="${CMD_PREAMBLE}. '${_clean}'; "
                    ;;
            esac
        done
    fi
}
