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

umask 077

if [[ "${EUID}" -ne 0 ]]; then
  echo "Run as root." >&2
  exit 1
fi

MODE="full"

while (($#)); do
  case "$1" in
    --mode)
      shift
      if (($# == 0)); then
        echo "Missing value for --mode" >&2
        exit 1
      fi
      MODE="$1"
      ;;
    --mode=*)
      MODE="${1#*=}"
      ;;
    *)
      echo "Unknown argument: $1" >&2
      exit 1
      ;;
  esac
  shift
done

case "${MODE}" in
  ready|full)
    ;;
  *)
    echo "Unsupported mode: ${MODE} (expected ready or full)" >&2
    exit 1
    ;;
esac

: "${RUN_AS_USER:=mt2.jakubkadlec.dev}"
: "${SERVER_HOST:=173.249.9.66}"
: "${AUTH_PORT:=11000}"
: "${CHANNEL_PORT:=11011}"
: "${SMOKE_BIN:=/home/${RUN_AS_USER}/metin/build/server-src/bin/metin_login_smoke}"
: "${CLIENT_VERSION:=1215955205}"
: "${MALL_PASSWORD:=000000}"

if [[ ! -x "${SMOKE_BIN}" ]]; then
  echo "Smoke binary not found: ${SMOKE_BIN}" >&2
  exit 1
fi

if ! id "${RUN_AS_USER}" >/dev/null 2>&1; then
  echo "Missing runtime user: ${RUN_AS_USER}" >&2
  exit 1
fi

unique_suffix() {
  printf '%s%s' "$(date +%s%N | tail -c 9)" "$(openssl rand -hex 2)"
}

DELETE_SUFFIX="$(unique_suffix)"
FULL_SUFFIX="$(unique_suffix)"

DELETE_LOGIN="smkd${DELETE_SUFFIX}"
DELETE_PASSWORD="$(openssl rand -hex 6)"
DELETE_SOCIAL_ID="$(date +%s%N | tail -c 14)"
DELETE_EMAIL="${DELETE_LOGIN}@example.invalid"
DELETE_CHARACTER_NAME="d${DELETE_SUFFIX}"
DELETE_PRIVATE_CODE="${DELETE_SOCIAL_ID: -7}"
DELETE_ACCOUNT_ID=""

FULL_LOGIN="smkf${FULL_SUFFIX}"
FULL_PASSWORD="$(openssl rand -hex 6)"
FULL_SOCIAL_ID="$(date +%s%N | tail -c 14)"
FULL_EMAIL="${FULL_LOGIN}@example.invalid"
FULL_CHARACTER_NAME="f${FULL_SUFFIX}"
FULL_ACCOUNT_ID=""

cleanup_account() {
  local account_id="$1"
  local login="$2"

  if [[ -n "${account_id}" ]]; then
    mysql player >/dev/null 2>&1 <<SQL || true
CREATE TEMPORARY TABLE smoke_pids AS
SELECT id FROM player WHERE account_id = ${account_id};

DELETE FROM item
WHERE owner_id IN (SELECT id FROM smoke_pids);

DELETE FROM affect
WHERE dwPID IN (SELECT id FROM smoke_pids);

DELETE FROM quest
WHERE dwPID IN (SELECT id FROM smoke_pids);

DELETE FROM player
WHERE id IN (SELECT id FROM smoke_pids);

DROP TEMPORARY TABLE smoke_pids;
SQL
  fi

  mysql player >/dev/null 2>&1 <<SQL || true
DELETE FROM player_index
WHERE id IN (
  SELECT id FROM account.account WHERE login='${login}'
);
SQL

  mysql account >/dev/null 2>&1 <<SQL || true
DELETE FROM account WHERE login='${login}';
SQL
}

create_account() {
  local login="$1"
  local password="$2"
  local social_id="$3"
  local email="$4"

  cleanup_account "" "${login}"

  mysql -N account <<SQL
INSERT INTO account (
  login,
  password,
  social_id,
  email,
  create_time,
  is_testor,
  status,
  newsletter,
  empire,
  name_checked,
  availDt,
  mileage,
  cash,
  gold_expire,
  silver_expire,
  safebox_expire,
  autoloot_expire,
  fish_mind_expire,
  marriage_fast_expire,
  money_drop_rate_expire,
  total_cash,
  total_mileage,
  channel_company,
  last_play
) VALUES (
  '${login}',
  PASSWORD('${password}'),
  '${social_id}',
  '${email}',
  NOW(),
  0,
  'OK',
  0,
  1,
  0,
  '2001-01-01 00:00:00',
  0,
  0,
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  '0000-00-00 00:00:00',
  0,
  0,
  '',
  NOW()
);
SELECT LAST_INSERT_ID();
SQL
}

create_player_index() {
  local account_id="$1"

  mysql player >/dev/null <<SQL
INSERT INTO player_index (id, pid1, pid2, pid3, pid4, empire)
VALUES (${account_id}, 0, 0, 0, 0, 1);
SQL
}

cleanup() {
  cleanup_account "${DELETE_ACCOUNT_ID}" "${DELETE_LOGIN}"
  cleanup_account "${FULL_ACCOUNT_ID}" "${FULL_LOGIN}"
}

trap cleanup EXIT

FULL_ACCOUNT_ID="$(create_account "${FULL_LOGIN}" "${FULL_PASSWORD}" "${FULL_SOCIAL_ID}" "${FULL_EMAIL}")"
create_player_index "${FULL_ACCOUNT_ID}"

if [[ "${MODE}" == "full" ]]; then
  DELETE_ACCOUNT_ID="$(create_account "${DELETE_LOGIN}" "${DELETE_PASSWORD}" "${DELETE_SOCIAL_ID}" "${DELETE_EMAIL}")"
  create_player_index "${DELETE_ACCOUNT_ID}"

  echo "Running create/delete healthcheck for temporary account ${DELETE_LOGIN}"
  sudo -iu "${RUN_AS_USER}" env METIN_LOGIN_SMOKE_PASSWORD="${DELETE_PASSWORD}" \
    "${SMOKE_BIN}" "${SERVER_HOST}" "${AUTH_PORT}" "${CHANNEL_PORT}" "${DELETE_LOGIN}" \
    --password-env=METIN_LOGIN_SMOKE_PASSWORD \
    --create-character-name="${DELETE_CHARACTER_NAME}" \
    --delete-private-code="${DELETE_PRIVATE_CODE}" \
    --client-version="${CLIENT_VERSION}"
fi

echo "Running ${MODE} login healthcheck for temporary account ${FULL_LOGIN}"
FULL_ARGS=(
  "${SMOKE_BIN}" "${SERVER_HOST}" "${AUTH_PORT}" "${CHANNEL_PORT}" "${FULL_LOGIN}"
  --password-env=METIN_LOGIN_SMOKE_PASSWORD
  --create-character-name="${FULL_CHARACTER_NAME}"
  --client-version="${CLIENT_VERSION}"
)

if [[ "${MODE}" == "full" ]]; then
  FULL_ARGS+=(--mall-password="${MALL_PASSWORD}")
fi

sudo -iu "${RUN_AS_USER}" env METIN_LOGIN_SMOKE_PASSWORD="${FULL_PASSWORD}" \
  "${FULL_ARGS[@]}"

echo "${MODE^} login healthcheck passed"
