#!/bin/bash
# ============================================================================
#  Files.ir Backup for WHM/cPanel - remote deployer
#
#  Install (the ONLY repo command you ever need, run as root):
#    curl -fsSL https://whm.hercol.ir/filesir.sh | bash
#
#  Everything else is a built-in command after that:
#    filesir_update | filesir_repair | filesir_uninstall [--purge]
#    filesir_status | filesir_version
#
#  (legacy: `... | bash -s -- update|repair|uninstall` still works and simply
#   forwards to the built-in CLI when it is installed)
#
#  Repo layout expected under BASE_URL:
#    filesir.sh                      this script
#    filesir-backup-latest.tar.gz    the module tarball
#    filesir-backup-latest.sha256    (optional) "SHA256  filename" checksum line
#    latest.txt                      (optional) plain version, e.g. 3.3.0
#
#  Repos: https://whm.hercol.ir (primary) -> https://whm.kinkhub.ir (mirror, automatic fallback)
#  Override the source with:  FILESIR_BASE_URL=https://my.mirror  ... | bash -s -- install
# ============================================================================
set -euo pipefail

# Two repos: primary + mirror. The first one that answers a 20-second probe is
# used; if the primary is unreachable the mirror takes over automatically.
# FILESIR_BASE_URL pins a single source (no fallback).
PRIMARY_URL="https://whm.hercol.ir"
MIRROR_URL="https://whm.kinkhub.ir"
TARBALL="filesir-backup-latest.tar.gz"
WORK="/usr/local/src/filesir-deploy.$$"
INSTALL_DIR="/usr/local/filesir_backup"

say(){ printf '\033[1;36m[filesir]\033[0m %s\n' "$*"; }
fail(){ printf '\033[1;31m[filesir] ERROR:\033[0m %s\n' "$*" >&2; rm -rf "$WORK"; exit 1; }

[ "$(id -u)" = "0" ] || fail "run as root."
CMD="${1:-install}"; shift || true
case "$CMD" in install|update|repair|uninstall) ;; *)
  echo "usage: $0 [install|update|repair|uninstall [--purge]]   (default: install)"; exit 1;; esac

# after the first install everything is built-in - forward legacy calls there
if [ "$CMD" != "install" ] && command -v filesir > /dev/null 2>&1; then
    say "forwarding to the built-in command: filesir $CMD $*"
    exec filesir "$CMD" "$@"
fi

installed_version(){ cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "-"; }

repo_candidates(){
  if [ -n "${FILESIR_BASE_URL:-}" ]; then echo "$FILESIR_BASE_URL"; return; fi
  echo "$PRIMARY_URL"; echo "$MIRROR_URL"
}
pick_repo(){
  local m
  for m in $(repo_candidates); do
    if curl -fsSL --connect-timeout 20 --max-time 25 -o /dev/null "$m/latest.txt" 2>/dev/null; then
      echo "$m"; return
    fi
    say "repo $m did not answer within 20s - trying the next one ..." >&2
  done
  repo_candidates | head -1
}
BASE_URL="$(pick_repo)"
say "using repo: $BASE_URL"

fetch_tree(){
  say "downloading $TARBALL from $BASE_URL ..."
  mkdir -p "$WORK"; cd "$WORK"
  if ! curl -fsSL --connect-timeout 20 -o "$TARBALL" "$BASE_URL/$TARBALL"; then
      ALT_OK=0
      for ALT in $(repo_candidates); do
        [ "$ALT" = "$BASE_URL" ] && continue
        say "download from $BASE_URL failed - retrying from $ALT ..."
        if curl -fsSL --connect-timeout 20 -o "$TARBALL" "$ALT/$TARBALL"; then BASE_URL="$ALT"; ALT_OK=1; break; fi
      done
      [ "$ALT_OK" = "1" ] || fail "download failed from every repo: $TARBALL"
  fi
  if curl -fsSL -o "$TARBALL.sha256" "$BASE_URL/$TARBALL.sha256" 2>/dev/null; then
      say "verifying sha256 ..."
      # accept either "HASH" or "HASH  filename"
      WANT=$(awk '{print $1}' "$TARBALL.sha256")
      GOT=$(sha256sum "$TARBALL" | awk '{print $1}')
      [ "$WANT" = "$GOT" ] || fail "sha256 mismatch (want $WANT got $GOT) - aborting."
      say "sha256 OK."
  else
      say "no checksum file published - skipping verification."
  fi
  tar -xzf "$TARBALL" || fail "tarball extraction failed."
  [ -d "$WORK/filesir-backup" ] || fail "unexpected tarball layout."
}

run_installer(){
  cd "$WORK/filesir-backup"
  if [ "${FILESIR_DEPLOY_DRY:-0}" = "1" ]; then
      say "DRY RUN: would execute ./install.sh (version $(cat VERSION))"
  else
      FILESIR_REPO_URL="$PRIMARY_URL" FILESIR_REPO_URL2="$MIRROR_URL" bash ./install.sh || fail "module installer failed."
  fi
}

case "$CMD" in
  install)
    fetch_tree
    say "installing Files.ir Backup $(cat "$WORK/filesir-backup/VERSION") ..."
    run_installer
    say "installed. Open WHM -> Plugins -> Files.ir"
    ;;
  update)
    CUR=$(installed_version)
    NEW=$(curl -fsSL "$BASE_URL/latest.txt" 2>/dev/null || true)
    if [ -n "$NEW" ] && [ "$NEW" = "$CUR" ]; then
        say "already on the latest version ($CUR) - nothing to do."
        exit 0
    fi
    fetch_tree
    say "updating $CUR -> $(cat "$WORK/filesir-backup/VERSION") (data and settings are kept) ..."
    run_installer
    say "update complete."
    ;;
  repair)
    fetch_tree
    say "repairing installation (re-copying files and re-registering; data untouched) ..."
    run_installer
    say "repair complete."
    ;;
  uninstall)
    fetch_tree
    cd "$WORK/filesir-backup"
    if [ "${FILESIR_DEPLOY_DRY:-0}" = "1" ]; then
        say "DRY RUN: would execute ./uninstall.sh $*"
    else
        bash ./uninstall.sh "$@" || fail "uninstaller failed."
    fi
    say "uninstalled.${*:+ (options: $*)}"
    ;;
esac
rm -rf "$WORK"
