#!/bin/bash
# This is installer script which placed on a https://files.microavia.com/utm.sh
set -euo pipefail

REGISTRY_URL="gitlab.microavia.com:4567"
DELIVERY_IMAGE="$REGISTRY_URL/microavia/utm/delivery:latest"
DOCKER_VERSION_MAX="28.5.2"
DOCKER_VERSION_MIN="28.0.0"
DOCKER_VERSION_STRING=""

get_latest_docker_version_string() {
    while read version_string version; do
        if dpkg --compare-versions "$version" le "$DOCKER_VERSION_MAX" && dpkg --compare-versions "$version" ge "$DOCKER_VERSION_MIN"; then
            if [[ -z "$DOCKER_VERSION_STRING" ]] || dpkg --compare-versions "$version" gt "$DOCKER_VERSION_STRING"; then
                DOCKER_VERSION_STRING="$version_string"
            fi
        fi
    done <<< "$(apt-cache madison docker-ce | awk '{version_string=$3; split(version_string, parts, ":"); split(parts[2], version_parts, "-"); print version_string, version_parts[1]}')"
}

command_exists() {
  command -v "$1" &> /dev/null
}

install_if_missing() {
  local pkg="$1"
  if ! command_exists "$pkg"; then
    echo "Installing $pkg..."
    sudo apt-get update
    sudo apt-get install -y "$pkg"
  else
    echo "$pkg is already installed"
  fi
}

install_docker_if_missing() {
  if ! command_exists docker; then
    echo "Installing Docker..."
    sudo apt update
    sudo apt install -y \
      ca-certificates curl gnupg lsb-release

    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
      sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    sudo apt update

    get_latest_docker_version_string
    if [[ -z "$DOCKER_VERSION_STRING" ]]; then
      echo "Unable to find a suitable docker version"
      exit 1
    fi

    sudo apt install -y docker-ce=$DOCKER_VERSION_STRING docker-ce-cli=$DOCKER_VERSION_STRING containerd.io
  elif dpkg --compare-versions "$(docker --version | awk '{print $3}' | sed 's/,//')" "lt" ${DOCKER_VERSION_MIN}; then
    read -p "Your version of docker is too old, do you want to update it? (All currently running containers will be stopped and may need rebuilding) [y/N]: " should_update
    SHOULD_UPDATE=${should_update,,}

    if [[ "$SHOULD_UPDATE" != "y" ]]; then
      exit 1
    fi

    sudo apt update
    sudo systemctl stop docker
    sudo docker ps -q | xargs -r docker stop

    get_latest_docker_version_string
    if [[ -z "$DOCKER_VERSION_STRING" ]]; then
      echo "Unable to find a suitable docker version"
      exit 1
    fi

    sudo apt install -y docker-ce=$DOCKER_VERSION_STRING docker-ce-cli=$DOCKER_VERSION_STRING containerd.io

  elif dpkg --compare-versions "$(docker --version | awk '{print $3}' | sed 's/,//')" "gt" ${DOCKER_VERSION_MAX}; then
    read -p "Your version of docker currently isn't supported. Do you wish to downgrade to the latest supported version ${DOCKER_VERSION_MAX}? \
(All currently running containers will be stopped and may need rebuilding) [y/N]: " should_downgrade
    SHOULD_DOWNGRADE=${should_downgrade,,}

    if [[ "$SHOULD_DOWNGRADE" != "y" ]]; then
      exit 1
    fi

    sudo apt update
    sudo systemctl stop docker
    sudo docker ps -q | xargs -r docker stop

    get_latest_docker_version_string
    if [[ -z "$DOCKER_VERSION_STRING" ]]; then
      echo "Unable to find a suitable docker version"
      exit 1
    fi

    sudo apt install -y docker-ce=$DOCKER_VERSION_STRING docker-ce-cli=$DOCKER_VERSION_STRING containerd.io --allow-downgrades

  else
    echo "docker is already installed"
  fi
}

configure_docker_group() {
  if ! getent group docker > /dev/null; then
    sudo groupadd docker
  fi

  if ! id -nG "$USER" | grep -qw docker; then
    sudo usermod -aG docker "$USER"
    echo "User $USER added to docker group. Please re-login to apply group changes."
  else
    echo "User $USER already in docker group"
  fi
}

check_logged_in_to_registry() {
  if [ -f ~/.docker/config.json ] && jq -e --arg registry "$REGISTRY_URL" '.auths[$registry]' ~/.docker/config.json > /dev/null 2>&1; then
    return 0
  else
    return 1
  fi
}

prompt_docker_login() {
  local username password
  read -p "Enter username/token name: " username < /dev/tty
  read -s -p "Enter password/token: " password < /dev/tty
  echo
  echo "$password" | docker login "$REGISTRY_URL" -u "$username" --password-stdin
}

# --- check deps ---

install_if_missing make
install_if_missing jq
install_docker_if_missing
configure_docker_group


if check_logged_in_to_registry; then
  echo "✅ Already logged in to $REGISTRY_URL"
else
  echo "🔐 Docker login required for $REGISTRY_URL"
  prompt_docker_login
fi

docker run --pull always --rm -v "$PWD:/output" \
  "$DELIVERY_IMAGE" \
  sh -c "cp -r /app/. /output"

echo -e '\n✅ Done. Run "make configure" to configure UTM services.'
