#!/usr/bin/env bash
# install_systemd_service — Pipeline que registra una app como servicio systemd local.
# Compone systemd_local_{install_unit, enable, start, status}.
set -euo pipefail

# Resolver repo root (asume que este archivo vive en bash/functions/pipelines/)
PIPELINE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$PIPELINE_DIR/../../.." && pwd)"
FN_DIR="$REPO_ROOT/bash/functions/infra"

# shellcheck source=/dev/null
source "$FN_DIR/systemd_local_install_unit.sh"
# shellcheck source=/dev/null
source "$FN_DIR/systemd_local_enable.sh"
# shellcheck source=/dev/null
source "$FN_DIR/systemd_local_start.sh"
# shellcheck source=/dev/null
source "$FN_DIR/systemd_local_status.sh"

usage() {
    cat <<'USAGE' >&2
install_systemd_service — registra una app como servicio systemd del sistema.

Uso:
  install_systemd_service --name <N> --exec <PATH> [opciones]

Obligatorios:
  --name <name>            Nombre del servicio (sin .service)
  --exec <path>            Ruta absoluta al binario/script ExecStart

Opcionales:
  --workdir <path>         WorkingDirectory (default: dirname de --exec)
  --user <user>            User del servicio (default: usuario actual)
  --description <text>     Description del unit (default: "<name> service")
  --env KEY=VAL            Variable de entorno (repetible)
  --after <units>          After= (default: network.target)
  --restart <policy>       Restart= (default: on-failure)
  --type <type>            Type= (default: simple)

Salida: JSON consolidado con los resultados de install_unit, enable, start y status.
USAGE
    exit 1
}

install_systemd_service() {
    local name="" exec_path="" workdir="" user="" description=""
    local after="network.target" restart="on-failure" type="simple"
    local -a envs=()

    while [[ $# -gt 0 ]]; do
        case "$1" in
            --name)         name="$2"; shift 2 ;;
            --exec)         exec_path="$2"; shift 2 ;;
            --workdir)      workdir="$2"; shift 2 ;;
            --user)         user="$2"; shift 2 ;;
            --description)  description="$2"; shift 2 ;;
            --env)          envs+=("$2"); shift 2 ;;
            --after)        after="$2"; shift 2 ;;
            --restart)      restart="$2"; shift 2 ;;
            --type)         type="$2"; shift 2 ;;
            -h|--help)      usage ;;
            *) echo "opción desconocida: $1" >&2; usage ;;
        esac
    done

    if [[ -z "$name" || -z "$exec_path" ]]; then
        echo "install_systemd_service: faltan --name y --exec" >&2
        usage
    fi

    [[ -z "$user" ]] && user="$(id -un)"
    [[ -z "$workdir" ]] && workdir="$(dirname "$exec_path")"
    [[ -z "$description" ]] && description="$name service"

    # Construir bloque Environment= (uno por línea, orden determinista)
    local env_block=""
    local e
    for e in "${envs[@]}"; do
        env_block+="Environment=\"$e\"
"
    done

    # Generar unit content (heredoc determinista)
    local unit_content
    unit_content="[Unit]
Description=$description
After=$after

[Service]
Type=$type
User=$user
WorkingDirectory=$workdir
${env_block}ExecStart=$exec_path
Restart=$restart
RestartSec=3

[Install]
WantedBy=multi-user.target
"

    echo "[install_systemd_service] instalando unit $name..." >&2
    local install_json enable_json start_json status_json
    install_json=$(systemd_local_install_unit "$name" "$unit_content")

    echo "[install_systemd_service] enable..." >&2
    enable_json=$(systemd_local_enable "$name")

    echo "[install_systemd_service] start..." >&2
    start_json=$(systemd_local_start "$name")

    # Darle un instante a systemd para estabilizar el estado
    sleep 1

    echo "[install_systemd_service] status..." >&2
    status_json=$(systemd_local_status "$name" 15)

    # JSON consolidado
    python3 - "$install_json" "$enable_json" "$start_json" "$status_json" <<'PY'
import json, sys
keys = ["install", "enable", "start", "status"]
out = {k: json.loads(v) for k, v in zip(keys, sys.argv[1:])}
print(json.dumps(out, indent=2))
PY
}

# Ejecución directa
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    install_systemd_service "$@"
fi
