#!/bin/bash

LOG_FILE="${TRIM_PKGVAR}/info.log"
PID_FILE="${TRIM_PKGVAR}/app.pid"

ARCH=$(uname -m)
[ "${ARCH}" = "aarch64" ] && ARCH="arm64"
IVENTOY_DIR="${TRIM_APPDEST}/server/${ARCH}"
IVENTOY_SH="${IVENTOY_DIR}/iventoy.sh"
IVENTOY_PID="/var/run/iventoy.pid"
SHARE_PATH="$(echo "${TRIM_DATA_SHARE_PATHS}" | cut -d':' -f1)"

log_msg() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >>${LOG_FILE}
}

setup_links() {
  # data    存放 License、配置文件等。
  # doc     存放软件相关说明文档
  # iso     放ISO文件的地方，可以在里面创建子目录。
  # lib     存放 iVentoy 运行所需的 LIB 文件，用户不要动这个目录。
  # log     存放 iVentoy 运行日志。
  # user    存放用户文件、第三方软件包、自动安装脚本等文件。
  #

  for d in data; do
    mkdir -p "${SHARE_PATH}/${d}" >/dev/null 2>&1 || true
    if [ "$(realpath "${SHARE_PATH}/${d}")" != "$(realpath "${IVENTOY_DIR}/${d}")" ]; then
      mv -f "${IVENTOY_DIR:?}/${d}"/. "${SHARE_PATH}/${d}"/ 2>/dev/null || true
      rm -rf "${IVENTOY_DIR:?}/${d}"
      ln -snf "${SHARE_PATH}/${d}" "${IVENTOY_DIR}/${d}"
      if [ -z "$(ls -A "${SHARE_PATH}/${d}" 2>/dev/null)" ] && [ -n "$(ls -A "${IVENTOY_DIR}/${d}.orig" 2>/dev/null)" ]; then
        cp -rf "${IVENTOY_DIR}/${d}.orig"/. "${SHARE_PATH}/${d}"/ 2>/dev/null || true
      fi
    fi
  done

  for d in iso; do
    mkdir -p "${wizard_iso_path:-"${SHARE_PATH}/${d}"}" >/dev/null 2>&1 || true
    if [ "$(realpath "${wizard_iso_path:-"${SHARE_PATH}/${d}"}")" != "$(realpath "${IVENTOY_DIR}/${d}")" ]; then
      mv -f "${IVENTOY_DIR:?}/${d}"/. "${wizard_iso_path:-"${SHARE_PATH}/${d}"}"/ 2>/dev/null || true
      rm -rf "${IVENTOY_DIR:?}/${d}"
      ln -snf "${wizard_iso_path:-"${SHARE_PATH}/${d}"}" "${IVENTOY_DIR}/${d}"
      if [ -z "$(ls -A "${wizard_iso_path:-"${SHARE_PATH}/${d}"}" 2>/dev/null)" ] && [ -n "$(ls -A "${IVENTOY_DIR}/${d}.orig" 2>/dev/null)" ]; then
        cp -rf "${IVENTOY_DIR}/${d}.orig"/. "${wizard_iso_path:-"${SHARE_PATH}/${d}"}"/ 2>/dev/null || true
      fi
    fi
  done

  for d in user; do
    mkdir -p "${wizard_user_path:-"${SHARE_PATH}/${d}"}" >/dev/null 2>&1 || true
    if [ "$(realpath "${wizard_user_path:-"${SHARE_PATH}/${d}"}")" != "$(realpath "${IVENTOY_DIR}/${d}")" ]; then
      mv -f "${IVENTOY_DIR:?}/${d}"/. "${wizard_user_path:-"${SHARE_PATH}/${d}"}"/ 2>/dev/null || true
      rm -rf "${IVENTOY_DIR:?}/${d}"
      ln -snf "${wizard_user_path:-"${SHARE_PATH}/${d}"}" "${IVENTOY_DIR}/${d}"
      if [ -z "$(ls -A "${wizard_user_path:-"${SHARE_PATH}/${d}"}" 2>/dev/null)" ] && [ -n "$(ls -A "${IVENTOY_DIR}/${d}.orig" 2>/dev/null)" ]; then
        cp -rf "${IVENTOY_DIR}/${d}.orig"/. "${wizard_user_path:-"${SHARE_PATH}/${d}"}"/ 2>/dev/null || true
      fi
    fi
  done

  for d in log; do
    mkdir -p "${TRIM_PKGVAR}/${d}" >/dev/null 2>&1 || true
    if [ "$(realpath "${TRIM_PKGVAR}/${d}")" != "$(realpath "${IVENTOY_DIR}/${d}")" ]; then
      mv -f "${IVENTOY_DIR:?}/${d}"/. "${TRIM_PKGVAR}/${d}"/ 2>/dev/null || true
      rm -rf "${IVENTOY_DIR:?}/${d}"
      ln -snf "${TRIM_PKGVAR}/${d}" "${IVENTOY_DIR}/${d}"
      if [ -z "$(ls -A "${TRIM_PKGVAR}/${d}" 2>/dev/null)" ] && [ -n "$(ls -A "${IVENTOY_DIR}/${d}.orig" 2>/dev/null)" ]; then
        cp -rf "${IVENTOY_DIR}/${d}.orig"/. "${TRIM_PKGVAR}/${d}"/ 2>/dev/null || true
      fi
    fi
  done
}

start_process() {
  if status; then
    return 0
  fi

  log_msg "Starting process ..."

  mkdir -p "${TRIM_PKGVAR}" >/dev/null 2>&1 || true
  setup_links
  [ -f "${SHARE_PATH}/data/config.dat" ] && ARGS="-R" || ARGS=""
  cd "${IVENTOY_DIR}" || true
  bash "${IVENTOY_SH}" ${ARGS:-} start >>${LOG_FILE} 2>&1

  local count=0
  while [ $count -lt 10 ]; do
    if [ -f "${IVENTOY_PID}" ]; then
      local pid
      pid=$(head -n 1 "${IVENTOY_PID}" | tr -d '[:space:]')
      if [ -n "${pid}" ] && kill -0 "${pid}" 2>/dev/null; then
        printf "%s" "${pid}" >${PID_FILE}
        log_msg "iVentoy started with PID ${pid}"
        return 0
      fi
    fi
    sleep 1
    count=$((count + 1))
    log_msg "Waiting for iVentoy to start... (${count}s/10s)"
  done

  log_msg "ERROR: iVentoy failed to start within timeout"
  return 1
}

stop_process() {
  log_msg "Stopping process ..."

  if [ -r "${PID_FILE}" ]; then
    pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')

    log_msg "pid=${pid}"
    if ! check_process "${pid}"; then
      # process not exist, delete pidfile
      rm -f "${PID_FILE}"
      rm -f "${IVENTOY_PID}"
      log_msg "remove pid file 1"
      return
    fi

    log_msg "send TERM signal to PID:${pid}..."
    kill -TERM ${pid} >>${LOG_FILE} 2>&1

    local count=0
    while check_process "${pid}" && [ $count -lt 10 ]; do
      sleep 1
      count=$((count + 1))
      log_msg "waiting process terminal... (${count}s/10s)"
    done

    if check_process "${pid}"; then
      log_msg "send KILL signal to PID:${pid}..."
      kill -KILL "${pid}"
      sleep 1
      rm -f "${PID_FILE}"
      rm -f "${IVENTOY_PID}"
    else
      log_msg "process killed... "
      rm -f "${PID_FILE}"
      rm -f "${IVENTOY_PID}"
    fi
  fi

  return 0
}

check_process() {
  local pid=$1
  if kill -0 "${pid}" 2>/dev/null; then
    return 0 # process exist
  else
    return 1 # process not exist
  fi
}

status() {
  if [ -f "${PID_FILE}" ]; then
    pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
    if check_process "${pid}"; then
      return 0
    else
      # Process is not running but pidfile exists - clean it up
      rm -f "${PID_FILE}"
      rm -f "${IVENTOY_PID}"
    fi
  fi

  return 1
}

case $1 in
  start)
    # run start command. exit 0 if success, exit 1 if failed
    start_process
    ;;
  stop)
    # run stop command. exit 0 if success, exit 1 if failed
    stop_process
    ;;
  status)
    # check application status command. exit 0 if running, exit 3 if not running
    if status; then
      exit 0
    else
      exit 3
    fi
    ;;
  *)
    exit 1
    ;;
esac
