#!/usr/bin/env bash

set -euo pipefail

SCRIPT_NAME="$(basename "$0")"

DEFAULT_SSH_USER="root"
DEFAULT_SSH_PORT="22"
DEFAULT_K3S_VERSION="v1.28.10+k3s1"
DEFAULT_K3SUP_VERSION="0.13.11"
DEFAULT_NAMESPACE="cubbit"
DEFAULT_MOUNT_BASE_PATH="/mnt/cubbit"
RED="$(printf '\033[0;31m')"
GREEN="$(printf '\033[0;32m')"
YELLOW="$(printf '\033[1;33m')"
BLUE="$(printf '\033[0;34m')"
NC="$(printf '\033[0m')"

SKIP_CLUSTER="no"
SKIP_DISKS="no"
AUTO_YES="no"
LIST_DISKS="no"
DELETE_MODE="no"
SERVER=""
SSH_USER="$DEFAULT_SSH_USER"
SSH_PORT="$DEFAULT_SSH_PORT"
SSH_KEY=""
K3S_VERSION="$DEFAULT_K3S_VERSION"
K3SUP_VERSION="$DEFAULT_K3SUP_VERSION"
K8S_CONTEXT=""
TLS_SAN=""
CLUSTER_NAMESPACE="$DEFAULT_NAMESPACE"
MOUNT_BASE_PATH="$DEFAULT_MOUNT_BASE_PATH"
DISKS=""
KUBECONFIG_OUTPUT=""
K3SUP_BIN=""

usage() {
  cat <<EOF
Prepare a single-node k3s cluster and/or disks using a remote server reachable via SSH.

Usage:
  ${SCRIPT_NAME} [options]

Note:
  The SSH user must have sudo/root privileges on the remote server.

Options:
  --server <hostname_or_ip>       Remote server (hostname or IP) used to install the kubernetes cluster
  --skip-cluster                  Skip cluster step (creation/deletion) [experimental, no support provided, use with caution]
  --skip-disks                    Skip disks step (preparation/deletion) [experimental, no support provided, use with caution]
  --list-disks                    List disks on the remote server and exit immediately [experimental, no support provided, use with caution]
  --delete                        Uninstall kubernetes and/or cleanup selected disks
  --disks </dev/disk1,/dev/disk2> List of comma-separated disks to prepare/cleanup
  --yes                           Skip interactive mode and proceed with defaults
  --user <ssh_user>               SSH user used to connect to the remote server. Default: ${DEFAULT_SSH_USER}
  --port <ssh_port>               SSH port used to connect to the remote server. Default: ${DEFAULT_SSH_PORT}
  --ssh-key <path>                Private key path used by SSH and k3sup to connect to the remote server. Default: your default SSH key
  --k3s-version <version>         k3s version. Default: ${DEFAULT_K3S_VERSION}
  --k3sup-version <version>       k3sup version to enforce locally. Default: ${DEFAULT_K3SUP_VERSION}
  --context <name>                context name to be used into the generated kubeconfig of the installed cluster. Default: derived from server
  --tls-san <value>               Value used for --tls-san in k3s extra args. Default: empty
  --namespace <name>              Namespace to be used to install Cubbit product. Default: ${DEFAULT_NAMESPACE}
  --kubeconfig-output <path>      Where to write kubeconfig locally. Default: ./kubeconfig-<context name>.yaml
  --mount-base-path <path>        Base path for mounted disks. Default: ${DEFAULT_MOUNT_BASE_PATH}
  --help                          Show this help.

Examples:
  ${SCRIPT_NAME} --server 203.0.113.10 --disks /dev/sdb,/dev/sdc --yes
  ${SCRIPT_NAME} --server server.example.com --skip-disks --ssh-key ~/.ssh/server.example.com.pem --context example-server
  ${SCRIPT_NAME} --server 203.0.113.10 --list-disks
  ${SCRIPT_NAME} --server 203.0.113.10 --delete --disks /dev/sdb,/dev/sdc
EOF
}

print_status() {
  printf '%b[INFO]%b %s\n' "${BLUE}" "${NC}" "$1"
}

print_success() {
  printf '%b[SUCCESS]%b %s\n' "${GREEN}" "${NC}" "$1"
}

print_warning() {
  printf '%b[WARNING]%b %s\n' "${YELLOW}" "${NC}" "$1" >&2
}

print_error() {
  printf '%b[ERROR]%b %s\n' "${RED}" "${NC}" "$1" >&2
}

fail() {
  print_error "$*"
  exit 1
}

# ensure that an option value is provided
require_option_value() {
  local option_name="$1"
  [[ $# -ge 2 && -n "${2-}" ]] || fail "missing value for ${option_name}"
}

check_local_prerequisites() {
  local missing=()
  local cmd=""

  for cmd in ssh curl uname awk grep xargs tr; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
      missing+=("$cmd")
    fi
  done

  if [[ ${#missing[@]} -gt 0 ]]; then
    fail "Local machine is missing required commands: ${missing[*]}"
  fi
}

check_remote_prerequisites() {
  local missing_remote=""

  # Intentionally check all remote prerequisites upfront, regardless of selected action.
  if ! missing_remote="$(ssh_run "sudo bash -s" <<'REMOTE_PREREQ'
set -euo pipefail

missing=()
for cmd in bash curl lsblk findmnt awk grep blkid mkfs.ext4 mount umount systemctl tee; do
  command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd")
done

if [ "${#missing[@]}" -gt 0 ]; then
  printf '%s ' "${missing[@]}"
  exit 1
fi
REMOTE_PREREQ
)"; then
    fail "Remote server is missing required commands: ${missing_remote:-unknown}"
  fi
}

# sanitize a string to be used as a kubeconfig context name
sanitize_context_name() {
  # - convert uppercase to lowercase
  # - replace one or more non [a-z0-9._-] characters with a single '-'
  printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9._-' '-'
}

# ask user input with an optional default value
prompt_value() {
  local prompt="$1"
  local default_value="${2-}"
  local value=""

  if [[ -n "$default_value" ]]; then
    printf '%s [%s]: ' "${prompt}" "${default_value}" >&2
    read -r value
    printf '%s' "${value:-$default_value}"
  else
    printf '%s: ' "${prompt}" >&2
    read -r value
    printf '%s' "$value"
  fi
}

prompt_yes_no() {
  local prompt="$1"
  local default_value="$2"
  local value=""
  local lower_value=""

  while true; do
    printf '%s [%s]: ' "${prompt}" "${default_value}" >&2
    read -r value
    value="${value:-$default_value}"
    lower_value="$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]')"
    case "$lower_value" in
      yes|y|true|t|1)
        printf 'yes'
        return
        ;;
      no|n|false|f|0)
        printf 'no'
        return
        ;;
    esac
    print_warning "Please answer with yes/no (or y/n)."
  done
}

# show a menu to select whether to run cluster setup, disk preparation, or both
select_actions_interactive() {
  local selected=""

  printf '%s\n' "Choose what to do:"
  printf '%s\n' "  1) Create cluster and prepare disks"
  printf '%s\n' "  2) Delete kubernetes and cleanup disks"
  while [[ -z "$selected" ]]; do
    printf 'Selection [1-2]: '
    read -r selected
    case "$selected" in
      1) SKIP_CLUSTER="no"; SKIP_DISKS="no" ;;
      2) DELETE_MODE="yes"; SKIP_CLUSTER="no"; SKIP_DISKS="no" ;;
      *) selected=""; print_warning "Invalid selection." ;;
    esac
  done
}

select_delete_actions_interactive() {
  SKIP_CLUSTER="no"
  SKIP_DISKS="no"

  if [[ "$(prompt_yes_no "Delete kubernetes (k3s)?" "yes")" == "no" ]]; then
    SKIP_CLUSTER="yes"
  fi
  if [[ "$(prompt_yes_no "Cleanup disks?" "yes")" == "no" ]]; then
    SKIP_DISKS="yes"
  fi
}

should_run_cluster() {
  [[ "$SKIP_CLUSTER" != "yes" ]]
}

should_run_disks() {
  [[ "$SKIP_DISKS" != "yes" ]]
}

# run a command on the remote server
ssh_run() {
  local ssh_args=(-p "$SSH_PORT")

  if [[ -n "$SSH_KEY" ]]; then
    ssh_args+=(-i "$SSH_KEY")
  fi

  ssh "${ssh_args[@]}" "${SSH_USER}@${SERVER}" "$@"
}

list_remote_disks() {
  print_status "Listing disks on remote server"
  ssh_run "bash -s" <<'REMOTE_SCRIPT'
set -euo pipefail

ROOT_DISK="$(lsblk -no PKNAME "$(findmnt -n -o SOURCE /)" | head -n1)"

lsblk -dn -o PATH,SIZE | while read -r PATH_VALUE SIZE_VALUE; do
  DEVICE_NAME="${PATH_VALUE##*/}"
  if [ "${DEVICE_NAME}" = "${ROOT_DISK}" ]; then
    printf '%s %s root\n' "${PATH_VALUE}" "${SIZE_VALUE}"
  else
    printf '%s %s\n' "${PATH_VALUE}" "${SIZE_VALUE}"
  fi
done
REMOTE_SCRIPT
}

# resolve action selection, ask for missing values, and validate inputs
handle_input() {
  if [[ "$SKIP_CLUSTER" == "no" && "$SKIP_DISKS" == "no" && "$AUTO_YES" != "yes" && "$LIST_DISKS" != "yes" && "$DELETE_MODE" != "yes" ]]; then
    select_actions_interactive
  fi

  if [[ "$AUTO_YES" == "yes" && -z "$SERVER" ]]; then
    fail "--server is required when using --yes"
  fi

  if [[ -z "$SERVER" ]]; then
    SERVER="$(prompt_value "Remote server hostname or IP")"
  fi
  [[ -n "$SERVER" ]] || fail "--server cannot be empty"

  [[ "$SSH_PORT" =~ ^[0-9]+$ ]] || fail "--port must be numeric"
  if [[ -n "$SSH_KEY" ]]; then
    [[ -f "$SSH_KEY" ]] || fail "ssh key not found: $SSH_KEY"
  fi
  check_remote_prerequisites

  if [[ "$LIST_DISKS" == "yes" ]]; then
    list_remote_disks
    exit 0
  fi

  if [[ "$DELETE_MODE" == "yes" ]]; then
    if [[ "$LIST_DISKS" == "yes" ]]; then
      fail "--delete cannot be combined with --list-disks"
    fi

    if [[ "$SKIP_CLUSTER" == "no" && "$SKIP_DISKS" == "no" && "$AUTO_YES" != "yes" ]]; then
      select_delete_actions_interactive
    fi

    if [[ "$SKIP_CLUSTER" == "yes" && "$SKIP_DISKS" == "yes" ]]; then
      fail "--skip-cluster and --skip-disks cannot be combined"
    fi
    if should_run_disks; then
      if [[ -z "$DISKS" ]]; then
        if [[ "$AUTO_YES" == "yes" ]]; then
          fail "--disks is required when using --yes --delete unless --skip-disks is set"
        fi
        DISKS="$(prompt_value "Disks to cleanup (comma-separated, e.g. /dev/sdb,/dev/sdc)")"
      fi
      if printf '%s' "$DISKS" | tr ',' '\n' | while read -r disk; do
        disk="$(printf '%s' "$disk" | xargs)"
        [[ -n "$disk" ]] || continue
        [[ "$disk" == /dev/* ]] || exit 1
      done; then
        :
      else
        fail "--disks must be a comma-separated list of full /dev/... paths"
      fi
    fi
    return
  fi

  if [[ "$AUTO_YES" == "yes" && "$SKIP_DISKS" != "yes" && -z "$DISKS" ]]; then
    fail "--disks is required when using --yes unless --skip-disks is set"
  fi

  if [[ -z "$K8S_CONTEXT" ]]; then
    K8S_CONTEXT="$(sanitize_context_name "$SERVER")"
  fi

  if [[ -z "$KUBECONFIG_OUTPUT" ]]; then
    KUBECONFIG_OUTPUT="$(pwd)/kubeconfig-${K8S_CONTEXT}.yaml"
  fi

  if should_run_disks; then
    if [[ -z "$DISKS" ]]; then
      DISKS="$(prompt_value "Disks to prepare (comma-separated, e.g. /dev/sdb,/dev/sdc)")"
    fi
  fi
  [[ "$SKIP_CLUSTER" == "yes" && "$SKIP_DISKS" == "yes" ]] && fail "--skip-cluster and --skip-disks cannot be combined"

  if should_run_disks; then
    [[ -n "$DISKS" ]] || fail "--disks is required when preparing disks"
    if printf '%s' "$DISKS" | tr ',' '\n' | while read -r disk; do
      disk="$(printf '%s' "$disk" | xargs)"
      [[ -n "$disk" ]] || continue
      [[ "$disk" == /dev/* ]] || exit 1
    done; then
      :
    else
      fail "--disks must be a comma-separated list of full /dev/... paths"
    fi
  fi
}

ensure_local_k3sup() {
  # k3sup runs locally and connects to the remote server over SSH.
  local tools_dir="/tmp/cubbit-tools/bin"
  local os=""
  local arch=""
  local k3sup_file="k3sup"
  local current_version=""

  mkdir -p "$tools_dir"

  os="$(uname | tr '[:upper:]' '[:lower:]')"
  arch="$(uname -m)"
  case "$arch" in
    x86_64) arch="amd64" ;;
    aarch64|arm64) arch="arm64" ;;
    *) fail "unsupported architecture for k3sup: $arch" ;;
  esac

  if [[ "$os" != "linux" ]]; then
    k3sup_file="${k3sup_file}-${os}"
  fi
  if [[ "$arch" != "amd64" ]]; then
    k3sup_file="${k3sup_file}-${arch}"
  fi

  K3SUP_BIN="${tools_dir}/k3sup"

  if [[ -x "$K3SUP_BIN" ]]; then
    current_version="$("$K3SUP_BIN" version 2>/dev/null | awk '/Version/ {print $2}' || true)"
  fi

  if [[ "$current_version" != "$K3SUP_VERSION" ]]; then
    print_status "Installing or updating local k3sup"
    curl -sS -L -o "$K3SUP_BIN" "https://github.com/alexellis/k3sup/releases/download/${K3SUP_VERSION}/${k3sup_file}"
    chmod +x "$K3SUP_BIN"
  fi

  current_version="$("$K3SUP_BIN" version 2>/dev/null | awk '/Version/ {print $2}' || true)"
  if [[ "$current_version" != "$K3SUP_VERSION" ]]; then
    print_warning "requested k3sup ${K3SUP_VERSION}, found ${current_version:-unknown}"
  fi
}

install_cluster() {
  local k3sup_args=()
  local k3s_extra_args="--node-external-ip=$SERVER --disable=traefik"

  if ssh_run "sudo k3s kubectl get nodes >/dev/null 2>&1"; then
    print_warning "k3s cluster already exists on remote server, skipping cluster installation"
    return
  fi

  ensure_local_k3sup

  if [[ -n "$TLS_SAN" ]]; then
    k3s_extra_args="$k3s_extra_args --tls-san=$TLS_SAN"
  fi

  print_status "Installing single-node k3s cluster"
  k3sup_args=(
    install
    --ip "$SERVER"
    --user "$SSH_USER"
    --ssh-port "$SSH_PORT"
    --cluster
    --k3s-version "$K3S_VERSION"
    --k3s-extra-args "$k3s_extra_args"
    --context "$K8S_CONTEXT"
    --local-path "$KUBECONFIG_OUTPUT"
  )
  if [[ -n "$SSH_KEY" ]]; then
    k3sup_args+=(--ssh-key "$SSH_KEY")
  fi
  mkdir -p "$(dirname "$KUBECONFIG_OUTPUT")"
  "$K3SUP_BIN" "${k3sup_args[@]}"

  print_status "Ensuring kubernetes namespace '$CLUSTER_NAMESPACE' exists"
  # check existence before creating it
  ssh_run "sudo k3s kubectl get namespace '$CLUSTER_NAMESPACE' >/dev/null 2>&1 || sudo k3s kubectl create namespace '$CLUSTER_NAMESPACE'"

  print_success "Kubeconfig written to $KUBECONFIG_OUTPUT"
}

delete_cluster() {
  print_status "Uninstalling kubernetes (k3s) from remote server"
  ssh_run "sudo bash -s" <<'REMOTE_DELETE'
set -euo pipefail

print_warning() {
  printf '\033[1;33m[WARNING]\033[0m %s\n' "$1" >&2
}

if [ -x /usr/local/bin/k3s-uninstall.sh ]; then
  sudo /usr/local/bin/k3s-uninstall.sh
else
  print_warning "k3s uninstall script not found at /usr/local/bin/k3s-uninstall.sh, skipping cluster uninstall"
fi
REMOTE_DELETE

  print_success "Delete action completed"
}

delete_disks() {
  local disk_list=()
  local raw_disk=""
  local device_path=""
  local target_path=""

  print_status "Cleaning disk mounts and fstab entries on remote server"
  IFS=',' read -r -a disk_list <<<"$DISKS"
  for raw_disk in "${disk_list[@]}"; do
    device_path="$(printf '%s' "$raw_disk" | xargs)"
    [[ -n "$device_path" ]] || continue
    target_path="${MOUNT_BASE_PATH}/${device_path##*/}"

    ssh_run "export CUBBIT_DEVICE_PATH='$device_path' CUBBIT_TARGET_PATH='$target_path'; bash -s" <<'REMOTE_DELETE_DISKS'
set -euo pipefail

print_warning() {
  printf '\033[1;33m[WARNING]\033[0m %s\n' "$1" >&2
}

ROOT_DISK="$(lsblk -no PKNAME "$(findmnt -n -o SOURCE /)" | head -n1)"
DEVICE_NAME="${CUBBIT_DEVICE_PATH##*/}"

if [ "${DEVICE_NAME}" = "${ROOT_DISK}" ]; then
  print_warning "Skipping ${CUBBIT_DEVICE_PATH}: this is the root disk"
  exit 0
fi

if ! lsblk -dn -o PATH | grep -qx "${CUBBIT_DEVICE_PATH}"; then
  print_warning "Skipping ${CUBBIT_DEVICE_PATH}: disk not found"
  exit 0
fi

# Unmount any mountpoint currently using the selected device.
if findmnt -rn -S "${CUBBIT_DEVICE_PATH}" >/dev/null 2>&1; then
  while read -r MOUNT_POINT; do
    [ -n "${MOUNT_POINT}" ] && sudo umount "${MOUNT_POINT}" || true
  done < <(findmnt -rn -S "${CUBBIT_DEVICE_PATH}" -o TARGET)
fi

UUID_VALUE="$(blkid -s UUID -o value "${CUBBIT_DEVICE_PATH}" || true)"
TMP_FSTAB="/tmp/fstab.cubbit.$$"
awk -v uuid="${UUID_VALUE}" -v target="${CUBBIT_TARGET_PATH}" '
  {
    if (uuid != "" && $1 == ("UUID=" uuid)) next
    if ($2 == target) next
    print
  }
' /etc/fstab > "${TMP_FSTAB}"
sudo mv "${TMP_FSTAB}" /etc/fstab

sudo rmdir "${CUBBIT_TARGET_PATH}" >/dev/null 2>&1 || true
sudo systemctl daemon-reload
REMOTE_DELETE_DISKS
  done

  print_success "Disk cleanup completed"
}

prepare_disks() {
  local disk_list=()
  local raw_disk=""
  local device_path=""
  local target_path=""
  local format_device=""
  local mount_device=""

  print_status "Preparing disks on remote server"
  IFS=',' read -r -a disk_list <<<"$DISKS"
  for raw_disk in "${disk_list[@]}"; do
    device_path="$(printf '%s' "$raw_disk" | xargs)"
    [[ -n "$device_path" ]] || continue

    if [[ "$AUTO_YES" == "yes" ]]; then
      format_device="yes"
      mount_device="yes"
    else
      format_device="$(prompt_yes_no "Format ${device_path}?" "yes")"
      mount_device="$(prompt_yes_no "Mount ${device_path}?" "yes")"
    fi

    if [[ "$format_device" != "yes" && "$mount_device" != "yes" ]]; then
      continue
    fi

    target_path="${MOUNT_BASE_PATH}/${device_path##*/}"
    ssh_run "export CUBBIT_DEVICE_PATH='$device_path' CUBBIT_TARGET_PATH='$target_path' CUBBIT_FORMAT_DEVICE='$format_device' CUBBIT_MOUNT_DEVICE='$mount_device'; bash -s" <<'REMOTE_SCRIPT'
set -euo pipefail

print_warning() {
  printf '\033[1;33m[WARNING]\033[0m %s\n' "$1" >&2
}

ROOT_DISK="$(lsblk -no PKNAME "$(findmnt -n -o SOURCE /)" | head -n1)"
DEVICE_NAME="${CUBBIT_DEVICE_PATH##*/}"

if [ "${DEVICE_NAME}" = "${ROOT_DISK}" ]; then
  print_warning "Skipping ${CUBBIT_DEVICE_PATH}: this is the root disk"
  exit 0
fi

if ! lsblk -dn -o PATH | grep -qx "${CUBBIT_DEVICE_PATH}"; then
  print_warning "Skipping ${CUBBIT_DEVICE_PATH}: disk not found"
  exit 0
fi

if [ "${CUBBIT_FORMAT_DEVICE}" = "yes" ]; then
  sudo mkfs.ext4 -F "${CUBBIT_DEVICE_PATH}"
fi

if [ "${CUBBIT_MOUNT_DEVICE}" = "yes" ]; then
  sudo mkdir -p "${CUBBIT_TARGET_PATH}"

  UUID_VALUE="$(blkid -s UUID -o value "${CUBBIT_DEVICE_PATH}" || true)"
  if [ -z "${UUID_VALUE}" ]; then
    print_warning "Skipping ${CUBBIT_DEVICE_PATH}: no filesystem UUID found"
    exit 0
  fi

  if ! grep -q "${UUID_VALUE}" /etc/fstab; then
    echo "UUID=${UUID_VALUE} ${CUBBIT_TARGET_PATH} ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab >/dev/null
  fi

  sudo mount "${CUBBIT_TARGET_PATH}" || sudo mount -a
  sudo systemctl daemon-reload
fi
REMOTE_SCRIPT
  done
}

parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --skip-cluster)
        SKIP_CLUSTER="yes"
        shift
        ;;
      --skip-disks)
        SKIP_DISKS="yes"
        shift
        ;;
      --yes)
        AUTO_YES="yes"
        shift
        ;;
      --list-disks)
        LIST_DISKS="yes"
        shift
        ;;
      --delete)
        DELETE_MODE="yes"
        shift
        ;;
      --server)
        require_option_value "$1" "${2-}"
        SERVER="${2-}"
        shift 2
        ;;
      --user)
        require_option_value "$1" "${2-}"
        SSH_USER="${2-}"
        shift 2
        ;;
      --port)
        require_option_value "$1" "${2-}"
        SSH_PORT="${2-}"
        shift 2
        ;;
      --ssh-key)
        require_option_value "$1" "${2-}"
        SSH_KEY="${2-}"
        shift 2
        ;;
      --k3s-version)
        require_option_value "$1" "${2-}"
        K3S_VERSION="${2-}"
        shift 2
        ;;
      --k3sup-version)
        require_option_value "$1" "${2-}"
        K3SUP_VERSION="${2-}"
        shift 2
        ;;
      --context)
        require_option_value "$1" "${2-}"
        K8S_CONTEXT="${2-}"
        shift 2
        ;;
      --tls-san)
        require_option_value "$1" "${2-}"
        TLS_SAN="${2-}"
        shift 2
        ;;
      --namespace)
        require_option_value "$1" "${2-}"
        CLUSTER_NAMESPACE="${2-}"
        shift 2
        ;;
      --kubeconfig-output)
        require_option_value "$1" "${2-}"
        KUBECONFIG_OUTPUT="${2-}"
        shift 2
        ;;
      --mount-base-path)
        require_option_value "$1" "${2-}"
        MOUNT_BASE_PATH="${2-}"
        shift 2
        ;;
      --disks)
        require_option_value "$1" "${2-}"
        DISKS="${2-}"
        shift 2
        ;;
      --help)
        usage
        exit 0
        ;;
      *)
        fail "unknown argument: $1"
        ;;
    esac
  done

}

main() {
  parse_args "$@"
  check_local_prerequisites

  handle_input

  if [[ "$DELETE_MODE" == "yes" ]]; then
    if should_run_cluster; then
      delete_cluster
    fi
    if should_run_disks; then
      delete_disks
    fi
    return
  fi

  if should_run_disks; then
    prepare_disks
  fi

  if should_run_cluster; then
    install_cluster
  fi

  print_success "Completed successfully"
}

main "$@"
