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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

resolve_repo_root() {
  local candidate
  for candidate in "${SCRIPT_DIR}/.." "${SCRIPT_DIR}/../.." "${PWD}"; do
    if [[ -f "${candidate}/credentials/.env" ]]; then
      (cd "${candidate}" && pwd)
      return 0
    fi
  done
  return 1
}

if ! REPO_ROOT="$(resolve_repo_root)"; then
  echo "Error: could not locate repository root containing credentials/.env" >&2
  exit 1
fi

ENV_FILE="${REPO_ROOT}/credentials/.env"
if [[ ! -f "${ENV_FILE}" ]]; then
  echo "Error: credentials file not found: ${ENV_FILE}" >&2
  exit 1
fi

load_env_value() {
  local key="$1"
  local line
  line="$(grep -E "^${key}=" "${ENV_FILE}" | tail -n 1 || true)"
  line="${line#*=}"
  line="${line%\"}"
  line="${line#\"}"
  line="${line%\'}"
  line="${line#\'}"
  printf '%s' "${line}"
}

DB_NAME="$(load_env_value MAILSHOTS_REMOTE_MYSQL_DB)"
MYSQL_USER="$(load_env_value REMOTE_MYSQL_USER)"
MYSQL_PASSWORD="$(load_env_value REMOTE_MYSQL_PASSWORD)"
REMOTE_MYSQL_HOST="$(load_env_value REMOTE_MYSQL_HOST)"
REMOTE_MYSQL_PORT="$(load_env_value REMOTE_MYSQL_PORT)"
LOCAL_TUNNEL_PORT="${LOCAL_PORT:-13306}"

# Match scripts/mysql_tunnel.sh defaults unless explicitly overridden.
MYSQL_HOST="${MYSQL_HOST:-127.0.0.1}"
MYSQL_PORT="${MYSQL_PORT:-${LOCAL_TUNNEL_PORT}}"

if [[ -z "${DB_NAME}" ]]; then
  echo "Error: MAILSHOTS_REMOTE_MYSQL_DB is missing in ${ENV_FILE}" >&2
  exit 1
fi
if [[ -z "${MYSQL_USER}" || -z "${MYSQL_PASSWORD}" ]]; then
  echo "Error: REMOTE_MYSQL_USER/REMOTE_MYSQL_PASSWORD missing in ${ENV_FILE}" >&2
  exit 1
fi
if [[ -z "${MYSQL_HOST}" || -z "${MYSQL_PORT}" ]]; then
  echo "Error: MYSQL host/port is empty. Set REMOTE_MYSQL_HOST/REMOTE_MYSQL_PORT or MYSQL_HOST/MYSQL_PORT." >&2
  exit 1
fi

DRY_RUN=0
AUTO_YES=0
INCLUDE_CREDENTIALS=0
USE_REMOTE=0
INCLUDE_MAILSHOT_TEST=0

# Strict, test-suite-specific markers only.
ARTEFACT_REGEX='^(e2e_|phase2_db_access_|phase3_|phase4_)'
MAILSHOT_PURPOSE_REGEX='^(e2e_|Phase3 Mailshot |Phase4 )'

usage() {
  cat <<'USAGE'
Usage: cleanup_testing_artefacts.sh [options]

Options:
  --dry-run              Show row counts only; make no changes.
  --yes                  Skip confirmation prompt.
  --include-credentials  Also delete test-marked rows in mailshot_credentials.
  --include-mailshot-test Also delete test-marked rows in mailshot_test.
  --remote               Connect directly to REMOTE_MYSQL_HOST:REMOTE_MYSQL_PORT.
  -h, --help             Show this help text.

Environment overrides:
  LOCAL_PORT, MYSQL_HOST, MYSQL_PORT
USAGE
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --dry-run) DRY_RUN=1 ;;
    --yes) AUTO_YES=1 ;;
    --include-credentials) INCLUDE_CREDENTIALS=1 ;;
    --include-mailshot-test) INCLUDE_MAILSHOT_TEST=1 ;;
    --remote) USE_REMOTE=1 ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Error: unknown option: $1" >&2
      usage
      exit 1
      ;;
  esac
  shift
done

if [[ "${USE_REMOTE}" -eq 1 ]]; then
  MYSQL_HOST="${REMOTE_MYSQL_HOST}"
  MYSQL_PORT="${REMOTE_MYSQL_PORT}"
fi

MYSQL_CMD=(mysql --protocol=TCP "-h${MYSQL_HOST}" "-P${MYSQL_PORT}" "-u${MYSQL_USER}" "-p${MYSQL_PASSWORD}" -N -B)

echo "Target database: ${DB_NAME}"
echo "MySQL endpoint: ${MYSQL_HOST}:${MYSQL_PORT}"
echo "Cleanup mode: selective delete only (no TRUNCATE)."
echo "Artefact regex: ${ARTEFACT_REGEX}"
echo "Mailshot purpose regex: ${MAILSHOT_PURPOSE_REGEX}"

for t in mailshot_last_run mailshot_queries mailshot_attachments mailshot_pdf_assets mailshots mailshot_credentials mailshot_test; do
  exists="$("${MYSQL_CMD[@]}" -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}' AND table_name='${t}';")"
  if [[ "${exists}" != "1" ]]; then
    echo "Error: required table ${DB_NAME}.${t} does not exist." >&2
    exit 1
  fi
done

candidate_counts_sql="
SELECT 'mailshot_queries' AS t, COUNT(*) AS c
FROM \`${DB_NAME}\`.\`mailshot_queries\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}'
UNION ALL
SELECT 'mailshot_attachments' AS t, COUNT(*) AS c
FROM \`${DB_NAME}\`.\`mailshot_attachments\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(\`file_name\`, '') REGEXP '${ARTEFACT_REGEX}'
UNION ALL
SELECT 'mailshot_pdf_assets' AS t, COUNT(*) AS c
FROM \`${DB_NAME}\`.\`mailshot_pdf_assets\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(\`file_name\`, '') REGEXP '${ARTEFACT_REGEX}'
UNION ALL
SELECT 'mailshots' AS t, COUNT(*) AS c
FROM \`${DB_NAME}\`.\`mailshots\`
WHERE COALESCE(\`Purpose\`, '') REGEXP '${MAILSHOT_PURPOSE_REGEX}'
   OR COALESCE(\`DataSource\`, '') REGEXP '${ARTEFACT_REGEX}'
UNION ALL
SELECT 'mailshot_last_run' AS t, COUNT(*) AS c
FROM \`${DB_NAME}\`.\`mailshot_last_run\` lr
WHERE COALESCE(lr.\`data_source\`, '') REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(lr.\`recipient_key\`, '') REGEXP '^phase[0-9]'
   OR lr.\`mailshot_id\` IN (
      SELECT m.\`id\` FROM \`${DB_NAME}\`.\`mailshots\` m
      WHERE COALESCE(m.\`Purpose\`, '') REGEXP '${MAILSHOT_PURPOSE_REGEX}'
         OR COALESCE(m.\`DataSource\`, '') REGEXP '${ARTEFACT_REGEX}'
   );"

echo
echo "Candidate rows to delete:"
"${MYSQL_CMD[@]}" -e "${candidate_counts_sql}" | while IFS=$'\t' read -r t c; do
  printf '  %-26s %s\n' "${t}" "${c}"
done

if [[ "${INCLUDE_MAILSHOT_TEST}" -eq 1 ]]; then
  c="$("${MYSQL_CMD[@]}" -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`mailshot_test\` WHERE COALESCE(\`Name\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') LIKE '%@example.test';")"
  printf '  %-26s %s\n' "mailshot_test (optional)" "${c}"
else
  echo "  mailshot_test               skipped (use --include-mailshot-test)"
fi

if [[ "${INCLUDE_CREDENTIALS}" -eq 1 ]]; then
  c="$("${MYSQL_CMD[@]}" -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`mailshot_credentials\` WHERE COALESCE(\`smtp_host\`, '') LIKE 'smtp.test.%' OR COALESCE(\`imap_host\`, '') LIKE 'imap.test.%' OR COALESCE(\`smtp_user\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`imap_user\`, '') REGEXP '${ARTEFACT_REGEX}';")"
  printf '  %-26s %s\n' "mailshot_credentials (optional)" "${c}"
else
  echo "  mailshot_credentials        skipped (use --include-credentials)"
fi

if [[ "${DRY_RUN}" -eq 1 ]]; then
  echo
  echo "Dry run complete. No changes made."
  exit 0
fi

if [[ "${AUTO_YES}" -ne 1 ]]; then
  echo
  read -r -p "Proceed to delete only the candidate test artefact rows above? [y/N] " reply
  if [[ ! "${reply}" =~ ^[Yy]$ ]]; then
    echo "Aborted. No changes made."
    exit 0
  fi
fi

delete_sql="
DELETE FROM \`${DB_NAME}\`.\`mailshot_last_run\`
WHERE COALESCE(\`data_source\`, '') REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(\`recipient_key\`, '') REGEXP '^phase[0-9]'
   OR \`mailshot_id\` IN (
      SELECT \`id\` FROM (
        SELECT m.\`id\`
        FROM \`${DB_NAME}\`.\`mailshots\` m
        WHERE COALESCE(m.\`Purpose\`, '') REGEXP '${MAILSHOT_PURPOSE_REGEX}'
           OR COALESCE(m.\`DataSource\`, '') REGEXP '${ARTEFACT_REGEX}'
      ) x
   );

DELETE FROM \`${DB_NAME}\`.\`mailshots\`
WHERE COALESCE(\`Purpose\`, '') REGEXP '${MAILSHOT_PURPOSE_REGEX}'
   OR COALESCE(\`DataSource\`, '') REGEXP '${ARTEFACT_REGEX}';

DELETE FROM \`${DB_NAME}\`.\`mailshot_queries\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}';

DELETE FROM \`${DB_NAME}\`.\`mailshot_attachments\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(\`file_name\`, '') REGEXP '${ARTEFACT_REGEX}';

DELETE FROM \`${DB_NAME}\`.\`mailshot_pdf_assets\`
WHERE \`name\` REGEXP '${ARTEFACT_REGEX}'
   OR COALESCE(\`file_name\`, '') REGEXP '${ARTEFACT_REGEX}';
"

"${MYSQL_CMD[@]}" -e "${delete_sql}"

if [[ "${INCLUDE_MAILSHOT_TEST}" -eq 1 ]]; then
  "${MYSQL_CMD[@]}" -e "DELETE FROM \`${DB_NAME}\`.\`mailshot_test\` WHERE COALESCE(\`Name\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') LIKE '%@example.test';"
fi

if [[ "${INCLUDE_CREDENTIALS}" -eq 1 ]]; then
  "${MYSQL_CMD[@]}" -e "DELETE FROM \`${DB_NAME}\`.\`mailshot_credentials\` WHERE COALESCE(\`smtp_host\`, '') LIKE 'smtp.test.%' OR COALESCE(\`imap_host\`, '') LIKE 'imap.test.%' OR COALESCE(\`smtp_user\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`imap_user\`, '') REGEXP '${ARTEFACT_REGEX}';"
fi

echo
echo "Cleanup complete. Remaining candidate row counts:"
"${MYSQL_CMD[@]}" -e "${candidate_counts_sql}" | while IFS=$'\t' read -r t c; do
  printf '  %-26s %s\n' "${t}" "${c}"
done

if [[ "${INCLUDE_MAILSHOT_TEST}" -eq 1 ]]; then
  c="$("${MYSQL_CMD[@]}" -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`mailshot_test\` WHERE COALESCE(\`Name\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`Email\`, '') LIKE '%@example.test';")"
  printf '  %-26s %s\n' "mailshot_test (optional)" "${c}"
fi

if [[ "${INCLUDE_CREDENTIALS}" -eq 1 ]]; then
  c="$("${MYSQL_CMD[@]}" -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`mailshot_credentials\` WHERE COALESCE(\`smtp_host\`, '') LIKE 'smtp.test.%' OR COALESCE(\`imap_host\`, '') LIKE 'imap.test.%' OR COALESCE(\`smtp_user\`, '') REGEXP '${ARTEFACT_REGEX}' OR COALESCE(\`imap_user\`, '') REGEXP '${ARTEFACT_REGEX}';")"
  printf '  %-26s %s\n' "mailshot_credentials (optional)" "${c}"
fi
