#!/usr/bin/env bash
set -euo pipefail

# -----------------------------
# OPSKY – Installeur Wazuh + Conf
# -----------------------------
# - Vérifie root
# - Télécharge installateur + paquets
# - Lance wazuh-install.sh -a
# - Extrait et sauvegarde les mots de passe Wazuh
# - Désactive les updates apt Wazuh
# - Crée l’arborescence OPSKY
# - Génère le mot de passe d’enrôlement agent (authd.pass)
# - Met à jour ossec.conf (auth + wodles)
# - Configure le wodle O365 (depuis INI +/ou arguments)
#
# Dépendances: bash, curl, tar, sed, awk, date, systemctl (si service)
#
# Usage (exemples):
#   chmod +x opsky-wazuh-install.sh
#   ./opsky-wazuh-install.sh --config ./opsky-wazuh.ini --enable-o365 yes
#   ./opsky-wazuh-install.sh --enable-o365 yes --o365-tenant-id "xxxxx" --o365-client-id "yyyyy" --o365-client-secret "zzzzz" --o365-initial-hours 24
#
# Tous les paramètres sont passables via arguments. Le fichier INI est optionnel.
# Les arguments priment sur le INI.

# ------------ Helpers ------------
log()  { printf "[%s] %s\n" "$(date +'%F %T')" "$*"; }
die()  { printf "ERROR: %s\n" "$*" >&2; exit 1; }

need_root() {
  if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
    die "Ce script doit être exécuté en root."
  fi
}

# INI reader: ini_get <file> <section> <key> -> value
ini_get() {
  local file="$1" section="$2" key="$3"
  awk -v section="$section" -v key="$key" '
    $0 ~ "^[ \t]*\\[" section "\\][ \t]*$" { insec=1; next }
    insec && $0 ~ "^[ \t]*\\[[^]]+\\][ \t]*$" { insec=0 }
    insec && $0 ~ "^[ \t]*" key "[ \t]*=" {
      sub(/^[ \t]*" key "[ \t]*=[ \t]*/, "", $0)
      gsub(/[ \t\r\n]+$/, "", $0)
      print $0; exit
    }
  ' "$file" 2>/dev/null || true
}

# Idempotent append: append once between markers
append_once() {
  local file="$1" marker="$2" content="$3"
  grep -q "$marker" "$file" 2>/dev/null && return 0
  printf "\n%s\n%s\n%s\n" "$marker" "$content" "$marker" >> "$file"
}

# Replace or add <auth> block in ossec.conf
ensure_auth_block() {
  local conf="$1"
  local tmp="$(mktemp)"
  if grep -q "<auth>" "$conf"; then
    # Remplace contenu <auth>...</auth>
    awk '
      /<auth>/,/<\/auth>/ { if (!printed) { print "<auth>\n    <disabled>no</disabled>\n    <use_password>yes</use_password>\n  </auth>"; printed=1 } next }
      { print }
    ' "$conf" > "$tmp"
  else
    # Ajoute avant </ossec_config>
    awk '
      /<\/ossec_config>/ && !printed {
        print "  <auth>\n    <disabled>no</disabled>\n    <use_password>yes</use_password>\n  </auth>"
        printed=1
      }
      { print }
    ' "$conf" > "$tmp"
  fi
  mv "$tmp" "$conf"
}

# ------------ Defaults ------------
DOWNLOAD_BASE="http://portaildev.opsky/download"
WAZUH_INSTALLER="wazuh-install.sh"
WAZUH_FILES_TAR="wazuh-v4.12.0.tar.gz"
OPSKY_FILES_TGZ="opsky-wazuh-files.tgz"

NON_INTERACTIVE="yes"

# Activation wodles (yes/no)
ENABLE_O365="no"
ENABLE_STEALED="no"
ENABLE_GWORKSPACE="no"

# O365 defaults (peuvent venir du INI ou des args)
O365_TENANT_ID=""
O365_CLIENT_ID=""
O365_CLIENT_SECRET=""
O365_LOGDIR="/var/ossec/logs/opsky/o365"
O365_RESOURCE="https://manage.office.com"
O365_DEBUG="False"
O365_INITIAL_HOURS="24"

# Répertoires
OSSEC_DIR="/var/ossec"
OPSKY_BASE="$OSSEC_DIR/opsky"
OPSKY_WODLES="$OPSKY_BASE/wodles"       # Chemin standardisé
OPSKY_WODLE_COMPAT="$OPSKY_BASE/wodle"  # Compat si déjà utilisé
OPSKY_SYNC="$OPSKY_BASE/wazuh_sync"
OPSKY_TRACECAT="$OPSKY_BASE/tracecat"
OPSKY_LOGS="$OSSEC_DIR/logs/opsky"

# Fichiers clés
OSSEC_CONF="$OSSEC_DIR/etc/ossec.conf"
AUTHD_PASS="$OSSEC_DIR/etc/authd.pass"
WAZUH_LIST="/etc/apt/sources.list.d/wazuh.list"
PASSWORDS_OUT="$OPSKY_BASE/wazuh-passwords.txt"

# Téléchargement / temporaires
TMP_DIR=""
CONFIG_FILE=""

# ------------ Args parsing ------------
while [[ $# -gt 0 ]]; do
  case "$1" in
    --config)                CONFIG_FILE="$2"; shift 2 ;;
    --download-base)         DOWNLOAD_BASE="$2"; shift 2 ;;
    --wazuh-installer)       WAZUH_INSTALLER="$2"; shift 2 ;;
    --wazuh-files)           WAZUH_FILES_TAR="$2"; shift 2 ;;
    --opsky-files)           OPSKY_FILES_TGZ="$2"; shift 2 ;;
    --temp-dir)              TMP_DIR="$2"; shift 2 ;;
    --non-interactive)       NON_INTERACTIVE="$2"; shift 2 ;;
    --enable-o365)           ENABLE_O365="$2"; shift 2 ;;
    --enable-stealed)        ENABLE_STEALED="$2"; shift 2 ;;
    --enable-gworkspace)     ENABLE_GWORKSPACE="$2"; shift 2 ;;
    --o365-tenant-id)        O365_TENANT_ID="$2"; shift 2 ;;
    --o365-client-id)        O365_CLIENT_ID="$2"; shift 2 ;;
    --o365-client-secret)    O365_CLIENT_SECRET="$2"; shift 2 ;;
    --o365-logdir)           O365_LOGDIR="$2"; shift 2 ;;
    --o365-resource)         O365_RESOURCE="$2"; shift 2 ;;
    --o365-debug)            O365_DEBUG="$2"; shift 2 ;;
    --o365-initial-hours)    O365_INITIAL_HOURS="$2"; shift 2 ;;
    -h|--help)
      cat <<'EOF'
OPSKY Wazuh installer

Options principales:
  --config <fichier.ini>          Fichier INI (section [O365]) à lire
  --download-base <url>           Base URL de téléchargement (def: http://portaildev.opsky/download)
  --wazuh-installer <nom>         Nom du script installateur (def: wazuh-install.sh)
  --wazuh-files <nom>             Nom du tar Wazuh files (def: wazuh-install-files.tar)
  --opsky-files <nom>             Nom du tgz OPSKY (def: opsky-wazuh-files.tgz)
  --temp-dir <dir>                Répertoire temporaire (def: mktemp -d)
  --non-interactive <yes|no>      Ne pas poser de questions (def: yes)

Activation des wodles:
  --enable-o365 <yes|no>          Active le wodle O365 (def: no)
  --enable-stealed <yes|no>       Active le wodle "stealed" (def: no)
  --enable-gworkspace <yes|no>    Active le wodle GWorkspace (def: no)

Paramètres O365 (override le INI):
  --o365-tenant-id <id>
  --o365-client-id <id>
  --o365-client-secret <secret>
  --o365-logdir <path>            (def: /var/ossec/logs/opsky/o365)
  --o365-resource <url>           (def: https://manage.office.com)
  --o365-debug <True|False>       (def: False)
  --o365-initial-hours <N>        (def: 24)

Exemples:
  ./opsky-wazuh-install.sh --config ./opsky-wazuh.ini --enable-o365 yes
  ./opsky-wazuh-install.sh --enable-o365 yes --o365-tenant-id T --o365-client-id C --o365-client-secret S
EOF
      exit 0
      ;;
    *)
      die "Argument inconnu: $1 (voir --help)"
      ;;
  esac
done

# ------------ Root check ------------
need_root

# ------------ Read INI if provided ------------
if [[ -n "${CONFIG_FILE}" && -f "${CONFIG_FILE}" ]]; then
  log "Lecture du INI: ${CONFIG_FILE}"
  O365_TENANT_ID="${O365_TENANT_ID:-$(ini_get "${CONFIG_FILE}" "O365" "TENANT_ID")}"_
