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

repo_url="${RIZOMA_ROUTER_REPO_URL:-https://repo.rizomasec.ru/router/redos}"
channel="${RIZOMA_ROUTER_CHANNEL:-stable}"
package_name="${RIZOMA_ROUTER_PACKAGE:-rizoma-router}"
run_setup="${RIZOMA_ROUTER_RUN_SETUP:-1}"
expected_rpm_key_fingerprint="7677CB111980CA204E7E2AD06D54FCDD94E2AD30"

while [ "$#" -gt 0 ]; do
  case "$1" in
    --repo-url)
      repo_url="${2:?missing value for --repo-url}"
      shift 2
      ;;
    --channel)
      channel="${2:?missing value for --channel}"
      shift 2
      ;;
    --package)
      package_name="${2:?missing value for --package}"
      shift 2
      ;;
    --skip-setup|--no-setup)
      run_setup=0
      shift
      ;;
    *)
      echo "install.sh: unknown argument: $1" >&2
      exit 1
      ;;
  esac
done

repo_url="${repo_url%/}"

fail() {
  echo "install.sh: $*" >&2
  exit 1
}

require_root() {
  if [ "$(id -u)" -ne 0 ]; then
    fail "run as root"
  fi
}

verify_rpm_key_file() {
  key_path="${1:?missing key path}"
  command -v gpg >/dev/null 2>&1 || fail "gpg is required to verify the Rizoma Router RPM signing key"
  if ! gpg --show-keys --with-colons "$key_path" 2>/dev/null |
    awk -F: '$1 == "fpr" { print toupper($10) }' |
    grep -Fxq "$expected_rpm_key_fingerprint"; then
    fail "downloaded RPM signing key does not contain expected fingerprint $expected_rpm_key_fingerprint"
  fi
}

install_apt() {
  require_debian_like_linux
  command -v apt-get >/dev/null 2>&1 || fail "apt-get not found"
  if ! command -v curl >/dev/null 2>&1; then
    apt-get update
    apt-get install -y curl ca-certificates
  fi

  install -d -m 0755 /usr/share/keyrings /etc/apt/sources.list.d
  curl -fsSL "$repo_url/keys/rizoma-router-archive-keyring.gpg" \
    -o /usr/share/keyrings/rizoma-router-archive-keyring.gpg
  chmod 0644 /usr/share/keyrings/rizoma-router-archive-keyring.gpg

  printf 'deb [signed-by=/usr/share/keyrings/rizoma-router-archive-keyring.gpg] %s/apt/%s ./\n' \
    "$repo_url" "$channel" > /etc/apt/sources.list.d/rizoma-router.list

  apt-get update
  apt-get install -y --no-install-recommends "$package_name"
}

is_alt_linux() {
  os_release_id_is "altlinux" && return 0
  [ -r /etc/altlinux-release ]
}

os_release_id_is() {
  expected="${1:?missing expected os id}"
  [ -r /etc/os-release ] || return 1
  # shellcheck disable=SC1091
  . /etc/os-release
  id="$(printf '%s' "${ID:-}" | tr '[:upper:]' '[:lower:]')"
  [ "$id" = "$expected" ]
}

require_redos_linux() {
  if ! os_release_id_is "redos"; then
    detected="unknown"
    if [ -r /etc/os-release ]; then
      # shellcheck disable=SC1091
      . /etc/os-release
      detected="${PRETTY_NAME:-${ID:-unknown}}"
    fi
    fail "unsupported OS for the Rizoma Router RED OS installer: $detected. Install on certified RED OS or use the installer built for your supported OS."
  fi
}

repo_target_os() {
  case "$repo_url" in
    */router/redos) echo "redos" ;;
    */router/alt) echo "altlinux" ;;
    */router/debian|*/router/ubuntu) echo "debian" ;;
    *) fail "unsupported Rizoma Router repository namespace: $repo_url" ;;
  esac
}

require_debian_like_linux() {
  if ! os_release_id_is "debian" && ! os_release_id_is "ubuntu"; then
    detected="unknown"
    if [ -r /etc/os-release ]; then
      # shellcheck disable=SC1091
      . /etc/os-release
      detected="${PRETTY_NAME:-${ID:-unknown}}"
    fi
    fail "unsupported OS for the Rizoma Router Debian/Ubuntu installer: $detected. Use the installer built for your supported OS."
  fi
}

require_alt_linux() {
  if ! is_alt_linux; then
    detected="unknown"
    if [ -r /etc/os-release ]; then
      # shellcheck disable=SC1091
      . /etc/os-release
      detected="${PRETTY_NAME:-${ID:-unknown}}"
    fi
    fail "unsupported OS for the Rizoma Router ALT Linux installer: $detected. Use the installer built for your supported OS."
  fi
}

alt_arch() {
  case "$(uname -m)" in
    x86_64) echo "x86_64" ;;
    aarch64|arm64) echo "aarch64" ;;
    *) fail "unsupported ALT architecture $(uname -m); supported: x86_64, aarch64" ;;
  esac
}

install_alt() {
  require_alt_linux
  command -v apt-get >/dev/null 2>&1 || fail "ALT apt-get not found"
  if ! command -v curl >/dev/null 2>&1; then
    apt-get update
    apt-get install -y curl ca-certificates
  fi
  if ! command -v gpg >/dev/null 2>&1; then
    apt-get update
    apt-get install -y gnupg
  fi

  arch="$(alt_arch)"
  install -d -m 0755 /etc/apt/sources.list.d
  key_tmp="$(mktemp)"
  curl -fsSL "$repo_url/keys/RPM-GPG-KEY-rizoma-router" -o "$key_tmp"
  verify_rpm_key_file "$key_tmp"
  rpm --import "$key_tmp"
  rm -f "$key_tmp"
  printf 'rpm %s/apt-rpm/%s %s classic\n' \
    "$repo_url" "$channel" "$arch" > /etc/apt/sources.list.d/rizoma-router.list

  apt-get update
  apt-get install -y "$package_name"
}

install_dnf() {
  require_redos_linux
  command -v dnf >/dev/null 2>&1 || fail "dnf not found"
  if ! command -v curl >/dev/null 2>&1; then
    dnf install -y curl ca-certificates
  fi
  if ! command -v gpg >/dev/null 2>&1; then
    dnf install -y gnupg2
  fi

  install -d -m 0755 /etc/yum.repos.d
  key_tmp="$(mktemp)"
  curl -fsSL "$repo_url/keys/RPM-GPG-KEY-rizoma-router" -o "$key_tmp"
  verify_rpm_key_file "$key_tmp"
  rpm --import "$key_tmp"
  rm -f "$key_tmp"

  cat > /etc/yum.repos.d/rizoma-router.repo <<EOF
[rizoma-router-$channel]
name=Rizoma Router $channel
baseurl=$repo_url/dnf/$channel/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=$repo_url/keys/RPM-GPG-KEY-rizoma-router
EOF

  install_or_upgrade_dnf_package "$package_name"
  install_or_upgrade_dnf_package suricata
  if command -v systemctl >/dev/null 2>&1; then
    systemctl disable --now suricata.service >/dev/null 2>&1 || true
  fi
}

install_or_upgrade_dnf_package() {
  local name="$1"
  if rpm -q "$name" >/dev/null 2>&1; then
    dnf upgrade -y --refresh --setopt=install_weak_deps=False "$name"
  else
    dnf install -y --refresh --setopt=install_weak_deps=False "$name"
  fi
}

run_first_boot_setup() {
  [ "$run_setup" = "1" ] || return 0
  command -v routerctl >/dev/null 2>&1 || fail "routerctl was not installed"
  if [ -r /dev/tty ] && [ -w /dev/tty ]; then
    echo "Starting Rizoma Router first-boot setup on /dev/tty." >/dev/tty
    routerctl setup </dev/tty >/dev/tty
  else
    echo "Rizoma Router package installed. Run first-boot setup from the router console:" >&2
    echo "  sudo routerctl setup" >&2
  fi
}

require_root
case "$channel" in
  stable|beta|canary) ;;
  *) fail "unsupported channel $channel; supported: stable, beta, canary" ;;
esac

case "$(repo_target_os)" in
  redos) install_dnf ;;
  altlinux) install_alt ;;
  debian) install_apt ;;
  *) fail "unsupported Rizoma Router repository namespace: $repo_url" ;;
esac

echo "Rizoma Router package installed from $repo_url ($channel)."
run_first_boot_setup
