#!/bin/bash

# ============================================================
# Docker MySQL 5.7 one-shot installer
# Published by: helper.sh
# Script note: generated with Claude and curated by helper.sh
# ============================================================

set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

IMAGE="mysql:5.7.44"
CONTAINER_NAME="mysql57"
DATA_DIR="/data/mysql5.7"
MYSQL_PORT="3306"
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-}"
MYSQL_DATABASE="${MYSQL_DATABASE:-}"
MYSQL_USER="${MYSQL_USER:-}"
MYSQL_PASSWORD="${MYSQL_PASSWORD:-}"

info()    { echo -e "${BLUE}[INFO]${NC}  $1"; }
success() { echo -e "${GREEN}[OK]${NC}    $1"; }
warning() { echo -e "${YELLOW}[WARN]${NC}  $1"; }
error()   { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }

usage() {
  cat <<'EOF'
Usage: install_mysql57_base_docker.sh [options]

Options:
  --data-dir PATH           Host directory to mount (default: /data/mysql5.7)
  --container-name NAME     Docker container name (default: mysql57)
  --port PORT               Host port mapped to MySQL 3306 (default: 3306)
  --root-password PASS      Root password for MySQL
  --database NAME           Optional database to create on first boot
  --user NAME               Optional non-root database user to create
  --password PASS           Password for the optional non-root database user
  -h, --help                Show this help message
EOF
}

generate_password() {
  if command -v openssl >/dev/null 2>&1; then
    openssl rand -base64 18 | tr -d '\n'
  else
    tr -dc 'A-Za-z0-9!@#%^+=' </dev/urandom | head -c 20
  fi
}

while [ $# -gt 0 ]; do
  case "$1" in
    --data-dir)
      DATA_DIR="$2"
      shift 2
      ;;
    --container-name)
      CONTAINER_NAME="$2"
      shift 2
      ;;
    --port)
      MYSQL_PORT="$2"
      shift 2
      ;;
    --root-password)
      MYSQL_ROOT_PASSWORD="$2"
      shift 2
      ;;
    --database)
      MYSQL_DATABASE="$2"
      shift 2
      ;;
    --user)
      MYSQL_USER="$2"
      shift 2
      ;;
    --password)
      MYSQL_PASSWORD="$2"
      shift 2
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      error "Unknown argument: $1"
      ;;
  esac
done

if [ "${EUID}" -ne 0 ]; then
  error "Run this script with root privileges: sudo bash $0"
fi

if ! command -v docker >/dev/null 2>&1; then
  error "Docker is not installed. Install Docker first with helper.sh/install_docker_ubuntu_2404.sh"
fi

if ! systemctl is-active --quiet docker; then
  info "Docker service is not running. Starting Docker..."
  systemctl start docker
fi

if [ -z "${MYSQL_ROOT_PASSWORD}" ]; then
  MYSQL_ROOT_PASSWORD="$(generate_password)"
  info "No root password was provided. Generated a strong random password."
fi

if [ -n "${MYSQL_USER}" ] && [ -z "${MYSQL_PASSWORD}" ]; then
  MYSQL_PASSWORD="$(generate_password)"
  info "Generated a password for MySQL user ${MYSQL_USER}."
fi

mkdir -p "${DATA_DIR}/data" "${DATA_DIR}/conf.d" "${DATA_DIR}/init"

if [ ! -f "${DATA_DIR}/conf.d/mysql57.cnf" ]; then
  info "Writing baseline MySQL config to ${DATA_DIR}/conf.d/mysql57.cnf"
  cat > "${DATA_DIR}/conf.d/mysql57.cnf" <<'EOF'
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_connections = 300
sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

[client]
default-character-set = utf8mb4
EOF
fi

ENV_ARGS=(
  -e "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}"
)

if [ -n "${MYSQL_DATABASE}" ]; then
  ENV_ARGS+=(-e "MYSQL_DATABASE=${MYSQL_DATABASE}")
fi
if [ -n "${MYSQL_USER}" ]; then
  ENV_ARGS+=(-e "MYSQL_USER=${MYSQL_USER}")
fi
if [ -n "${MYSQL_PASSWORD}" ]; then
  ENV_ARGS+=(-e "MYSQL_PASSWORD=${MYSQL_PASSWORD}")
fi

info "Pulling ${IMAGE} ..."
docker pull "${IMAGE}"

if docker ps -a --format '{{.Names}}' | grep -Fx "${CONTAINER_NAME}" >/dev/null 2>&1; then
  warning "Container ${CONTAINER_NAME} already exists. Recreating it with the current mount layout."
  docker rm -f "${CONTAINER_NAME}" >/dev/null
fi

info "Starting ${CONTAINER_NAME} ..."
docker run -d \
  --name "${CONTAINER_NAME}" \
  --restart unless-stopped \
  -p "${MYSQL_PORT}:3306" \
  -v "${DATA_DIR}/data:/var/lib/mysql" \
  -v "${DATA_DIR}/conf.d:/etc/mysql/conf.d:ro" \
  -v "${DATA_DIR}/init:/docker-entrypoint-initdb.d" \
  "${ENV_ARGS[@]}" \
  "${IMAGE}" >/dev/null

MYSQL_READY="0"
for _ in $(seq 1 30); do
  if docker exec "${CONTAINER_NAME}" mysqladmin ping -h 127.0.0.1 -uroot "-p${MYSQL_ROOT_PASSWORD}" --silent >/dev/null 2>&1; then
    MYSQL_READY="1"
    break
  fi
  sleep 2
done

if [ "${MYSQL_READY}" = "1" ]; then
  success "MySQL health check passed"
else
  warning "Container started, but MySQL is not ready yet. Check docker logs -f ${CONTAINER_NAME}"
fi

echo ""
echo -e "${GREEN}============================================================${NC}"
echo -e "${GREEN} MySQL 5.7 container deployment completed                    ${NC}"
echo -e "${GREEN}============================================================${NC}"
echo ""
echo -e "  ${BLUE}Image:${NC}            ${IMAGE}"
echo -e "  ${BLUE}Container:${NC}        ${CONTAINER_NAME}"
echo -e "  ${BLUE}MySQL port:${NC}       ${MYSQL_PORT}"
echo -e "  ${BLUE}Mounted data dir:${NC} ${DATA_DIR}"
echo -e "  ${BLUE}Root password:${NC}    ${MYSQL_ROOT_PASSWORD}"
echo ""
if [ -n "${MYSQL_DATABASE}" ]; then
  echo -e "  ${BLUE}Initial database:${NC} ${MYSQL_DATABASE}"
fi
if [ -n "${MYSQL_USER}" ]; then
  echo -e "  ${BLUE}Initial user:${NC}     ${MYSQL_USER}"
  echo -e "  ${BLUE}User password:${NC}    ${MYSQL_PASSWORD}"
fi
echo ""
echo -e "  ${YELLOW}Editable host paths:${NC}"
echo -e "    ${DATA_DIR}/data"
echo -e "    ${DATA_DIR}/conf.d/mysql57.cnf"
echo -e "    ${DATA_DIR}/init/"
echo ""
echo -e "  ${YELLOW}Useful commands:${NC}"
echo -e "    docker ps"
echo -e "    docker logs -f ${CONTAINER_NAME}"
echo -e "    docker exec -it ${CONTAINER_NAME} mysql -uroot -p"
echo -e "    docker exec -it ${CONTAINER_NAME} mysqladmin ping -uroot -p"
echo ""
