#!/bin/sh

PACKAGE_NAME="GivEnergyInsight"
PACKAGE_ROOT="${SYNOPKG_PKGDEST:-/var/packages/${PACKAGE_NAME}/target}"
PACKAGE_VAR="${SYNOPKG_PKGVAR:-/var/packages/${PACKAGE_NAME}/var}"
PID_FILE="${PACKAGE_VAR}/givenergy-insight.pid"
LOG_FILE="${PACKAGE_VAR}/givenergy-insight.log"
SERVER_FILE="${PACKAGE_ROOT}/app/synology/runtime/server.mjs"

find_node() {
  for candidate in \
    /var/packages/Node.js_v20/target/usr/local/bin/node \
    /var/packages/Node.js_v20/target/bin/node \
    /var/packages/Node.js_v18/target/usr/local/bin/node \
    /var/packages/Node.js_v18/target/bin/node \
    /usr/local/bin/node \
    /usr/bin/node
  do
    if [ -x "$candidate" ]; then
      printf '%s\n' "$candidate"
      return 0
    fi
  done
  return 1
}

read_pid() {
  if [ -f "$PID_FILE" ]; then
    pid="$(sed -n '1p' "$PID_FILE" 2>/dev/null)"
  else
    pid=""
  fi
}

is_running() {
  read_pid
  [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null
}

start_service() {
  if is_running; then
    return 0
  fi

  NODE_BIN="$(find_node)" || {
    echo "Node.js v18 or newer is required but was not found" >&2
    return 1
  }
  [ -f "$SERVER_FILE" ] || {
    echo "GivEnergy Insight server files are missing" >&2
    return 1
  }

  mkdir -p "$PACKAGE_VAR" || return 1
  chmod 700 "$PACKAGE_VAR" 2>/dev/null || true
  if [ -f "$LOG_FILE" ] && [ "$(wc -c < "$LOG_FILE" 2>/dev/null)" -gt 5242880 ]; then
    mv -f "$LOG_FILE" "${LOG_FILE}.previous"
  fi

  umask 077
  SYNOPKG_PKGVAR="$PACKAGE_VAR" \
  GIVENERGY_INSIGHT_DSM_PORT="43819" \
  GIVENERGY_INSIGHT_DSM_AUTH="on" \
  nohup "$NODE_BIN" "$SERVER_FILE" >> "$LOG_FILE" 2>&1 &
  pid=$!
  printf '%s\n' "$pid" > "$PID_FILE"

  attempts=0
  while [ "$attempts" -lt 20 ]; do
    if ! kill -0 "$pid" 2>/dev/null; then
      rm -f "$PID_FILE"
      return 1
    fi
    if "$NODE_BIN" -e "fetch('http://127.0.0.1:43819/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" >/dev/null 2>&1; then
      return 0
    fi
    attempts=$((attempts + 1))
    sleep 1
  done

  kill "$pid" 2>/dev/null || true
  rm -f "$PID_FILE"
  return 1
}

stop_service() {
  if ! is_running; then
    rm -f "$PID_FILE"
    return 0
  fi

  kill -TERM "$pid" 2>/dev/null || true
  attempts=0
  while kill -0 "$pid" 2>/dev/null && [ "$attempts" -lt 20 ]; do
    attempts=$((attempts + 1))
    sleep 1
  done
  if kill -0 "$pid" 2>/dev/null; then
    kill -KILL "$pid" 2>/dev/null || true
  fi
  rm -f "$PID_FILE"
  return 0
}

case "$1" in
  start)
    start_service
    ;;
  stop)
    stop_service
    ;;
  status)
    if is_running; then
      exit 0
    fi
    [ -f "$PID_FILE" ] && exit 1
    exit 3
    ;;
  *)
    exit 0
    ;;
esac

exit $?
