#!/bin/bash
# Root: base services for manual exchange (like merchant start_base_services_for_taler.sh).
# Then interactive shell as taler-exchange-httpd → run start_exchange.sh there.
#
# Secmods run as dedicated users (not httpd) — started here as root.
# httpd is started by /usr/local/bin/start_exchange.sh as taler-exchange-httpd.
#
# Usage:
#   /root/start_base_services_for_taler_exchange.sh
#   /root/start_base_services_for_taler_exchange.sh --no-shell

set -e
CONF=/etc/taler-exchange/taler-exchange.conf
LOG_DIR=/var/log/taler-exchange
PWD_BIN=/usr/local/bin
EXCHANGE_STARTER=start_exchange.sh

if [ "$(id -u)" -ne 0 ]; then
  echo "Run as root" >&2
  exit 1
fi

NO_SHELL=0
for arg in "$@"; do
  case "$arg" in
    --no-shell|-n) NO_SHELL=1 ;;
    --help|-h)
      echo "Usage: $0 [--no-shell]"
      exit 0
      ;;
  esac
done

# --- Debian postgresql defaults (pg_createcluster layout) ---
ensure_postgresql() {
  echo "  Debian perms on /etc/postgresql + data/log/run..."
  if [ -d /etc/postgresql ]; then
    chown -R root:postgres /etc/postgresql
    find /etc/postgresql -type d -exec chmod 755 {} \;
    find /etc/postgresql -type f -name '*.conf' -exec chmod 640 {} \;
  fi
  chown -R postgres:postgres /var/lib/postgresql /var/log/postgresql 2>/dev/null || true
  mkdir -p /var/run/postgresql
  chown postgres:postgres /var/run/postgresql
  chmod 2775 /var/run/postgresql 2>/dev/null || chmod 775 /var/run/postgresql

  if pg_isready -q 2>/dev/null; then
    echo "  already accepting connections"
    pg_isready || true
    return 0
  fi

  rm -f /var/run/postgresql/.s.PGSQL.*.lock 2>/dev/null || true
  if ! pgrep -u postgres -x postgres >/dev/null 2>&1; then
    rm -f /var/lib/postgresql/*/main/postmaster.pid 2>/dev/null || true
  fi

  if command -v pg_ctlcluster >/dev/null 2>&1 && command -v pg_lsclusters >/dev/null 2>&1; then
    while read -r ver name _rest; do
      [ -n "$ver" ] || continue
      echo "  pg_ctlcluster $ver $name start"
      pg_ctlcluster "$ver" "$name" start 2>/dev/null || true
    done < <(pg_lsclusters --no-header 2>/dev/null || true)
  fi
  if ! pg_isready -q 2>/dev/null; then
    if [ -x /etc/init.d/postgresql ]; then
      /etc/init.d/postgresql start || true
    else
      service postgresql start || true
    fi
  fi
  sleep 1
  pg_isready || true
}

echo "Create log + runtime dirs... giving permission to taler-exchange users:"
mkdir -p "$LOG_DIR"
mkdir -p /run/taler-exchange/secmod-rsa /run/taler-exchange/secmod-cs \
         /run/taler-exchange/secmod-eddsa /run/taler-exchange/httpd
chown root:root /run/taler-exchange
chmod 755 /run/taler-exchange
chown taler-exchange-secmod-rsa:taler-exchange-secmod /run/taler-exchange/secmod-rsa
chown taler-exchange-secmod-cs:taler-exchange-secmod /run/taler-exchange/secmod-cs
chown taler-exchange-secmod-eddsa:taler-exchange-secmod /run/taler-exchange/secmod-eddsa
chown taler-exchange-httpd:www-data /run/taler-exchange/httpd
chmod 755 /run/taler-exchange/secmod-rsa /run/taler-exchange/secmod-cs /run/taler-exchange/secmod-eddsa
chmod 750 /run/taler-exchange/httpd
chown taler-exchange-httpd: "$LOG_DIR"
chmod 755 "$LOG_DIR"

# Package default: each secmod user owns its tree (keys/ must not be root-owned).
mkdir -p /var/lib/taler-exchange/secmod-rsa /var/lib/taler-exchange/secmod-cs \
         /var/lib/taler-exchange/secmod-eddsa
chown -R taler-exchange-secmod-rsa:taler-exchange-secmod /var/lib/taler-exchange/secmod-rsa
chown -R taler-exchange-secmod-cs:taler-exchange-secmod /var/lib/taler-exchange/secmod-cs
chown -R taler-exchange-secmod-eddsa:taler-exchange-secmod /var/lib/taler-exchange/secmod-eddsa
chmod 700 /var/lib/taler-exchange/secmod-rsa /var/lib/taler-exchange/secmod-cs \
          /var/lib/taler-exchange/secmod-eddsa

echo "Start base services needed for Taler Exchange."
echo ""

echo "1. postgresql:"
ensure_postgresql

# Linux COMM is 15 chars — never pgrep -x for long names; match full path in args.
start_bg() {
  local user="$1"; shift
  local name="$1"; shift
  local bin="$1"
  if ps -eo args= 2>/dev/null | grep -F "$bin" | grep -v grep >/dev/null 2>&1; then
    echo "  already running: $name"
    return 0
  fi
  echo "  start $name as $user"
  nohup runuser -u "$user" -- "$@" >>"$LOG_DIR/${name}.log" 2>&1 </dev/null &
  disown 2>/dev/null || true
  sleep 0.3
}

echo "2. crypto secmods:"
start_bg taler-exchange-secmod-rsa taler-exchange-secmod-rsa \
  /usr/bin/taler-exchange-secmod-rsa -c "$CONF" -L INFO
start_bg taler-exchange-secmod-cs taler-exchange-secmod-cs \
  /usr/bin/taler-exchange-secmod-cs -c "$CONF" -L INFO
start_bg taler-exchange-secmod-eddsa taler-exchange-secmod-eddsa \
  /usr/bin/taler-exchange-secmod-eddsa -c "$CONF" -L INFO

echo "3. wire/db helpers (need wire config to stay up):"
start_bg taler-exchange-aggregator taler-exchange-aggregator \
  /usr/bin/taler-exchange-aggregator -c "$CONF" -L INFO || true
start_bg taler-exchange-closer taler-exchange-closer \
  /usr/bin/taler-exchange-closer -c "$CONF" -L INFO || true
start_bg taler-exchange-wire taler-exchange-wirewatch \
  /usr/bin/taler-exchange-wirewatch -c "$CONF" -L INFO || true
start_bg taler-exchange-wire taler-exchange-transfer \
  /usr/bin/taler-exchange-transfer -c "$CONF" -L INFO || true

if [ "$NO_SHELL" -eq 1 ]; then
  echo "Base services started (--no-shell). Next: runuser -u taler-exchange-httpd -- $PWD_BIN/$EXCHANGE_STARTER [--restart]"
  exit 0
fi

echo "4. Switching now to user taler-exchange-httpd, in $PWD_BIN; find executable $EXCHANGE_STARTER there!"
echo ""
cd "$PWD_BIN"
# same pattern as merchant: -u and -s/--shell are mutually exclusive on util-linux runuser
exec runuser -u taler-exchange-httpd -- bash
