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

MIRROR_BASE="https://mirror.parsvds.com"
BACKUP_DIR="/root/parsvds-apt-backup"
RHEL_BACKUP_DIR="/root/parsvds-yum-backup"
OLD_REPO_DIR="/etc/yum.repos.d/old-repo"

# -------- Colors / UI --------
RED="\e[31m"
GRN="\e[32m"
YLW="\e[33m"
BLU="\e[34m"
CYN="\e[36m"
DIM="\e[2m"
RST="\e[0m"
BOLD="\e[1m"

hr() { echo -e "${DIM}------------------------------------------------------------${RST}"; }
say() { echo -e "${CYN}[*]${RST} $*"; }
ok() { echo -e "${GRN}[OK]${RST} $*"; }
warn() { echo -e "${YLW}[!]${RST} $*"; }
die() { echo -e "${RED}[X]${RST} $*"; exit 1; }

logo() {
  clear || true
  echo -e "${BLU}${BOLD}"
  cat <<'EOF'
              ____                         _
             |  _ \ __ _ _ __ _____   ____| |___
             | |_) / _` | '__/ __\ \ / / _` / __|
             |  __/ (_| | |  \__ \\ V / (_| \__ \
             |_|   \__,_|_|  |___/ \_/ \__,_|___/


               ParsVDS Public Mirror Setup
EOF
  echo -e "${RST}"
  hr
}

pause() { read -rp "Press Enter to continue..." _; }

# -------- Args --------
BASE=0
EPEL=0
MARIADB=0
INTERACTIVE=0

usage() {
  cat <<EOF
ParsVDS Mirror Auto Setup

Usage:
  sudo bash parsvds-mirror-setup.sh [--base] [--epel] [--mariadb]

If no options are given, interactive menu will appear.
EOF
}

if [[ $# -eq 0 ]]; then
  INTERACTIVE=1
fi

while [[ $# -gt 0 ]]; do
  case "$1" in
    --base) BASE=1 ;;
    --epel) EPEL=1 ;;
    --mariadb) MARIADB=1 ;;
    -h|--help) usage; exit 0 ;;
    *) die "Unknown arg: $1" ;;
  esac
  shift
done
# -------- Detect OS --------
OS_ID="unknown"
OS_VER=""
OS_CODE=""
OS_LIKE=""

if [[ -f /etc/os-release ]]; then
  . /etc/os-release
  OS_ID="${ID:-unknown}"
  OS_VER="${VERSION_ID:-}"
  OS_CODE="${VERSION_CODENAME:-${UBUNTU_CODENAME:-}}"
  OS_LIKE="${ID_LIKE:-}"
fi

is_apt=0
is_rhel=0

command -v apt >/dev/null 2>&1 && is_apt=1
(command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1) && is_rhel=1

PM="dnf"
if ! command -v dnf >/dev/null 2>&1; then
  PM="yum"
fi

# -------- Helper: cleanup apt backups --------
cleanup_apt_backups() {
  sudo mkdir -p "$BACKUP_DIR"
  shopt -s nullglob
  local moved=0
  for f in /etc/apt/sources.list.d/*.bak.* /etc/apt/sources.list.d/*.backup.*; do
    [[ -f "$f" ]] || continue
    sudo mv "$f" "$BACKUP_DIR/" && moved=1
  done
  shopt -u nullglob

  [[ $moved -eq 1 ]] && ok "Moved old APT backup files to $BACKUP_DIR to avoid apt warnings."
}

# -------- APT BASE --------
switch_apt_base() {
  say "Detected APT-based system: ${BOLD}${OS_ID}${RST} (${OS_CODE})"
  sudo mkdir -p "$BACKUP_DIR"

  if [[ -f /etc/apt/sources.list ]]; then
    sudo cp /etc/apt/sources.list "$BACKUP_DIR/sources.list.bak.$(date +%F-%T)" || true
  fi

  if [[ -f /etc/apt/sources.list ]]; then
    sudo sed -i \
      -e "s|http[s]*://[^ ]*ubuntu.com/ubuntu|$MIRROR_BASE/ubuntu|g" \
      -e "s|http://deb.debian.org/debian|$MIRROR_BASE/debian|g" \
      -e "s|http://security.debian.org/debian-security|$MIRROR_BASE/debian-security|g" \
      -e "s|https://deb.debian.org/debian|$MIRROR_BASE/debian|g" \
      -e "s|https://security.debian.org/debian-security|$MIRROR_BASE/debian-security|g" \
      /etc/apt/sources.list || true
  fi

  shopt -s nullglob
  for f in /etc/apt/sources.list.d/*.sources; do
    base="$(basename "$f")"
    sudo cp "$f" "$BACKUP_DIR/${base}.bak.$(date +%F-%T)"
    sudo sed -i \
      -e "s|http[s]*://[^ ]*ubuntu.com/ubuntu|$MIRROR_BASE/ubuntu|g" \
      -e "s|http://deb.debian.org/debian|$MIRROR_BASE/debian|g" \
      -e "s|http://security.debian.org/debian-security|$MIRROR_BASE/debian-security|g" \
      -e "s|https://deb.debian.org/debian|$MIRROR_BASE/debian|g" \
      -e "s|https://security.debian.org/debian-security|$MIRROR_BASE/debian-security|g" \
      "$f"
  done
  shopt -u nullglob

  cleanup_apt_backups

  sudo apt update
  ok "APT BASE repos switched to ParsVDS."
  ok "Backups stored in $BACKUP_DIR"
}

# -------- RHEL helper: safely set baseurl per section --------
rhel_set_section_baseurl() {
  local file="$1" section="$2" url="$3"
  local tmp; tmp="$(mktemp)"
  awk -v sec="$section" -v url="$url" '
    BEGIN{insec=0; done=0}
    $0 ~ "^[[:space:]]*\\[" sec "\\][[:space:]]*$" {insec=1; done=0; print; next}
    $0 ~ "^[[:space:]]*\\[.*\\][[:space:]]*$" && insec==1 && $0 !~ "^[[:space:]]*\\[" sec "\\][[:space:]]*$" {
      if(done==0){print "baseurl=" url; done=1}
      insec=0; print; next
    }
    insec==1 {
      if($0 ~ "^[[:space:]]*mirrorlist="){sub("^[[:space:]]*mirrorlist=","#mirrorlist=",$0); print; next}
      if($0 ~ "^[[:space:]]*metalink="){sub("^[[:space:]]*metalink=","#metalink=",$0); print; next}
      if($0 ~ "^[[:space:]]*#?[[:space:]]*baseurl="){print "baseurl=" url; done=1; next}
      print; next
    }
    {print}
    END{ if(insec==1 && done==0) print "baseurl=" url }
  ' "$file" > "$tmp"
  sudo cp "$tmp" "$file"
  rm -f "$tmp"
}

# -------- RHEL BASE (Alma/CentOS smart) --------
switch_rhel_base() {
  say "Detected RHEL-based system: ${BOLD}${OS_ID}${RST} ${DIM}${OS_VER}${RST}"
  sudo mkdir -p "$RHEL_BACKUP_DIR/$(date +%F-%T)"
  sudo cp /etc/yum.repos.d/*.repo "$RHEL_BACKUP_DIR/$(date +%F-%T)/" 2>/dev/null || true

  if [[ -f /etc/yum.repos.d/almalinux-parsvds.repo ]]; then
    say "Found almalinux-parsvds.repo. Moving default Alma repos to $OLD_REPO_DIR to avoid duplicates..."
    sudo mkdir -p "$OLD_REPO_DIR"
    sudo mv /etc/yum.repos.d/almalinux*.repo "$OLD_REPO_DIR/" 2>/dev/null || true
  fi

  # ===== AlmaLinux =====
  if ls /etc/yum.repos.d/almalinux*.repo >/dev/null 2>&1; then
    say "Configuring AlmaLinux repos (smart for 8/9 + any arch)"
    for f in /etc/yum.repos.d/almalinux*.repo; do
      rhel_set_section_baseurl "$f" "baseos"    "$MIRROR_BASE/almalinux/\$releasever/BaseOS/\$basearch/os/"
      rhel_set_section_baseurl "$f" "appstream" "$MIRROR_BASE/almalinux/\$releasever/AppStream/\$basearch/os/"
      rhel_set_section_baseurl "$f" "extras"    "$MIRROR_BASE/almalinux/\$releasever/extras/\$basearch/os/"
    done
  fi

  # ===== CentOS / CentOS Stream =====
  if ls /etc/yum.repos.d/CentOS-*.repo >/dev/null 2>&1; then
    local is_stream=0
    grep -qi "Stream" /etc/centos-release /etc/redhat-release 2>/dev/null && is_stream=1
    local major="${OS_VER%%.*}"
    local root=""

    if [[ $is_stream -eq 1 ]]; then
      say "Configuring CentOS Stream repos (smart for 8/9 Stream)"
      root="$MIRROR_BASE/centos/${major}-stream"
      for f in /etc/yum.repos.d/CentOS-*.repo; do
        rhel_set_section_baseurl "$f" "BaseOS"     "$root/BaseOS/\$basearch/os/"
        rhel_set_section_baseurl "$f" "baseos"     "$root/BaseOS/\$basearch/os/"
        rhel_set_section_baseurl "$f" "AppStream"  "$root/AppStream/\$basearch/os/"
        rhel_set_section_baseurl "$f" "appstream"  "$root/AppStream/\$basearch/os/"
        rhel_set_section_baseurl "$f" "extras"     "$root/extras/\$basearch/os/"
        rhel_set_section_baseurl "$f" "CRB"        "$root/CRB/\$basearch/os/"
        rhel_set_section_baseurl "$f" "crb"        "$root/CRB/\$basearch/os/"
        rhel_set_section_baseurl "$f" "PowerTools" "$root/PowerTools/\$basearch/os/"
        rhel_set_section_baseurl "$f" "powertools" "$root/PowerTools/\$basearch/os/"
      done
    else
      say "Configuring CentOS Linux repos (smart for 7)"
      root="$MIRROR_BASE/centos/\$releasever"
      for f in /etc/yum.repos.d/CentOS-*.repo; do
        sudo sed -ri 's/^[[:space:]]*mirrorlist=/#mirrorlist=/; s/^[[:space:]]*metalink=/#metalink=/' "$f"
        rhel_set_section_baseurl "$f" "base"    "$root/os/\$basearch/"
        rhel_set_section_baseurl "$f" "updates" "$root/updates/\$basearch/"
        rhel_set_section_baseurl "$f" "extras"  "$root/extras/\$basearch/"
      done
    fi
  fi

  sudo "$PM" clean all
  sudo "$PM" makecache
  ok "RHEL BASE repos switched to ParsVDS."
  ok "Backups stored in $RHEL_BACKUP_DIR"
}

# -------- EPEL --------
setup_epel() {
  say "Installing EPEL and switching to ParsVDS"
  sudo "$PM" install epel-release -y

  sudo sed -ri 's/^[[:space:]]*metalink=/#metalink=/; s/^[[:space:]]*mirrorlist=/#mirrorlist=/' /etc/yum.repos.d/epel*.repo
  sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*baseurl=.*|baseurl=$MIRROR_BASE/epel/\$releasever/Everything/\$basearch|g" /etc/yum.repos.d/epel*.repo

  sudo "$PM" clean all
  sudo "$PM" makecache
  ok "EPEL installed & mirrored to ParsVDS."
}

# -------- MariaDB --------
setup_mariadb_repo_apt() {
  sudo apt-get install -y curl gnupg ca-certificates
  curl -LsS https://mariadb.org/mariadb_release_signing_key.asc | sudo apt-key add -

  local codename
  codename="$(lsb_release -cs 2>/dev/null || echo "$OS_CODE")"
  echo "deb [arch=amd64] $MIRROR_BASE/mariadb/repo/10.11/$OS_ID $codename main" | \
    sudo tee /etc/apt/sources.list.d/mariadb.list >/dev/null

  sudo apt update
  ok "MariaDB APT repo set to ParsVDS."
}

setup_mariadb_repo_rhel_upstream() {
  sudo "$PM" install -y curl ca-certificates

  local major="${OS_VER%%.*}"
  local arch="$(uname -m)"
  local archdir="amd64"
  case "$arch" in
    x86_64) archdir="amd64" ;;
    aarch64|arm64) archdir="aarch64" ;;
    *) archdir="$arch" ;;
  esac

  local rhdir="rhel8-${archdir}"
  [[ "${major:-8}" -ge 9 ]] && rhdir="rhel9-${archdir}"

  sudo tee /etc/yum.repos.d/MariaDB.repo >/dev/null <<EOF
[mariadb]
name=MariaDB (ParsVDS Mirror)
baseurl=$MIRROR_BASE/mariadb/yum/10.11/${rhdir}
gpgkey=https://mariadb.org/mariadb_release_signing_key.asc
gpgcheck=1
enabled=1
EOF

  sudo "$PM" makecache
  ok "MariaDB upstream repo set to ParsVDS (${rhdir})."
}

setup_mariadb() {
  say "Installing MariaDB via ParsVDS"

  if [[ $is_apt -eq 1 ]]; then
    setup_mariadb_repo_apt
    read -rp "Install MariaDB server now? (y/n) " a
    if [[ "${a:-}" =~ ^[Yy]$ ]]; then
      sudo apt install -y mariadb-server
      sudo systemctl enable --now mariadb
      ok "MariaDB server installed and started."
    fi
    return
  fi

  local mode="simple"
  if [[ $INTERACTIVE -eq 1 && -t 0 ]]; then
    echo
    echo "Choose MariaDB install mode:"
    echo "  1) Simple (recommended) - OS built-in mariadb-server"
    echo "  2) Upstream 10.11 - MariaDB repo via ParsVDS (advanced)"
    read -rp "Enter choice [1/2]: " ch
    [[ "$ch" == "2" ]] && mode="upstream"
  fi

  if [[ "$mode" == "upstream" ]]; then
    say "Using upstream MariaDB 10.11 repo (advanced)"
    sudo dnf module disable mariadb -y || true
    setup_mariadb_repo_rhel_upstream
    read -rp "Install MariaDB server now? (y/n) " a
    if [[ "${a:-}" =~ ^[Yy]$ ]]; then
      sudo "$PM" install -y MariaDB-server
      sudo systemctl enable --now mariadb || true
      ok "MariaDB upstream server installed and started."
    fi
  else
    say "Using SIMPLE OS MariaDB packages (recommended)"
    read -rp "Install MariaDB server now? (y/n) " a
    if [[ "${a:-}" =~ ^[Yy]$ ]]; then
      sudo "$PM" install -y mariadb-server
      sudo systemctl enable --now mariadb || true
      ok "MariaDB (OS built-in) server installed and started."
    fi
  fi
}

# -------- Menus --------
menu_apt() {
  while true; do
    logo
    echo -e "OS: ${BOLD}${OS_ID}${RST} ${DIM}${OS_VER}${RST} (${OS_CODE})"
    hr
    echo -e "${BOLD}Choose an option:${RST}"
    echo "  1) Switch BASE repos to ParsVDS (Ubuntu/Debian)"
    echo "  2) Setup MariaDB repo (ParsVDS mirror)"
    echo "  3) Run ALL (BASE + MariaDB)"
    echo "  0) Exit"
    hr
    read -rp "Enter choice: " c

    case "$c" in
      1) switch_apt_base; pause ;;
      2) setup_mariadb; pause ;;
      3) switch_apt_base; setup_mariadb; pause ;;
      0) exit 0 ;;
      *) warn "Invalid choice"; sleep 1 ;;
    esac
  done
}

menu_rhel() {
  while true; do
    logo
    echo -e "OS: ${BOLD}${OS_ID}${RST} ${DIM}${OS_VER}${RST}"
    hr
    echo -e "${BOLD}Choose an option:${RST}"
    echo "  1) Switch BASE repos to ParsVDS (Alma/CentOS smart)"
    echo "  2) Install + switch EPEL to ParsVDS"
    echo "  3) Install MariaDB (simple / optional upstream)"
    echo "  4) Run ALL (BASE + EPEL + MariaDB)"
    echo "  0) Exit"
    hr
    read -rp "Enter choice: " c

    case "$c" in
      1) switch_rhel_base; pause ;;
      2) setup_epel; pause ;;
      3) setup_mariadb; pause ;;
      4) switch_rhel_base; setup_epel; setup_mariadb; pause ;;
      0) exit 0 ;;
      *) warn "Invalid choice"; sleep 1 ;;
    esac
  done
}

# -------- Run --------
if [[ $INTERACTIVE -eq 1 ]]; then
  if [[ $is_apt -eq 1 ]]; then
    menu_apt
  elif [[ $is_rhel -eq 1 ]]; then
    menu_rhel
  else
    die "Unknown system / package manager."
  fi
else
  if [[ $BASE -eq 1 ]]; then
    if [[ $is_apt -eq 1 ]]; then
      switch_apt_base
    else
      switch_rhel_base
    fi
  fi

  [[ $EPEL -eq 1 ]] && setup_epel
  [[ $MARIADB -eq 1 ]] && setup_mariadb

  echo
  ok "DONE. ParsVDS Mirror setup finished."
fi
