#!/usr/bin/env bash
export DEBIAN_FRONTEND=noninteractive
export CURL_USER_AGENT=NimeOps-UA

LOCAL_BIN_DIR=/usr/local/bin
LAYEROPS_USER=layerops
LAYEROPS_GROUP=$LAYEROPS_USER
LAYEROPS_HOME_DIR=/opt/layerops
LAYEROPS_DATA_DIR=/data/layerops
LAYEROPS_BIN_DIR=${LAYEROPS_HOME_DIR}/bin
LAYEROPS_WORKER_PATH=${LAYEROPS_BIN_DIR}/worker
LAYEROPS_WORKER_UPDATE_SCRIPT=${LOCAL_BIN_DIR}/layerops-worker-update
LAYEROPS_ETC_DIR=${LAYEROPS_HOME_DIR}/etc
LAYEROPS_ETC_DEFAULT_FILE=${LAYEROPS_ETC_DIR}/default
LAYEROPS_WORKER_SYSTEMD_FILE=/etc/systemd/system/layerops-worker@.service
LAYEROPS_WORKER_UPDATE_SYSTEMD_FILE=/etc/systemd/system/layerops-worker-update.service
LAYEROPS_WORKER_UPDATE_SYSTEMD_TIMER_FILE=/etc/systemd/system/layerops-worker-update.timer
LAYEROPS_WORKER_VERSION_CHECK=${LAYEROPS_API_URL}/v1/environments/${ENVIRONMENT_GROUP_UUID}/workerVersion

VGNAME=layerops
LVNAME=data

SUDO_FILE=/etc/sudoers.d/99-layerops-users

WIREGUARD_CONFIG_DIR=/etc/wireguard
WIREGUARD_INTERFACE=wg0
WIREGUARD_MTU=1200
WIREGUARD_SUBNET=172.24.0.0/13
WIREGUARD_CONFIG_FILE=${WIREGUARD_CONFIG_DIR}/${WIREGUARD_INTERFACE}.conf
WIREGUARD_TEMPLATE_FILE=${WIREGUARD_CONFIG_FILE}.tmpl
WIREGUARD_QUICK_RELOAD_PATH=${LAYEROPS_BIN_DIR}/wg-quick-up-reload
WIREGUARD_RELOAD_PATH=${LAYEROPS_BIN_DIR}/wireguard_start_or_reload

DOCKER_DATA_DIR=${LAYEROPS_DATA_DIR}/docker
DOCKER_GROUP=docker
DOCKER_DAEMON_FILE=/etc/docker/daemon.json

STATS_PORT=9889
STATS_CACHE_TTL="15s"

NODE_EXPORTER_VERSION=1.10.2
NODE_EXPORTER_BIND_PORT=9888
NODE_EXPORTER_SYSTEMD_FILE=/etc/systemd/system/node_exporter.service
NODE_EXPORTER_USERGROUP=node_exporter

SPIRE_CONFIG_DIR=${LAYEROPS_ETC_DIR}/spire
SPIRE_AGENT_CONFIG_FILE=${SPIRE_CONFIG_DIR}/agent.conf
SPIRE_AGENT_DATA_DIR=${LAYEROPS_DATA_DIR}/spire/agent
SPIRE_VERSION=1.14.0
SPIRE_URL=https://github.com/spiffe/spire/releases/download/v${SPIRE_VERSION}/spire-${SPIRE_VERSION}-linux-amd64-musl.tar.gz
SPIRE_AGENT_PATH=${LAYEROPS_BIN_DIR}/spire-agent
SPIRE_AGENT_LAUNCH_SCRIPT=${LAYEROPS_BIN_DIR}/start-spire-agent
SPIRE_SERVER_IP=172.24.0.1
SPIRE_BIND_PORT=8081
SPIRE_HTTP_CHALLENGE_PORT=1020
SPIRE_TRUST_DOMAIN=${ENVIRONMENT_GROUP_UUID:0:8}.layerops.io
SPIRE_AGENT_SYSTEMD_FILE=/etc/systemd/system/spire-agent.service
SPIRE_TRUST_BUNDLE_URL=${LAYEROPS_ORCHESTRATOR_URL}/environments/spire-trust-bundle?environmentGroupUuid=${ENVIRONMENT_GROUP_UUID}

function usage {
  cat << EOF
Usage: $(basename "${BASH_SOURCE[0]}") [init|enable_support|disable_support|clean]
EOF
  exit 0
}

function check_envvars() {
  MISSING=""
  for envvar in ENVIRONMENT_GROUP_UUID INSTANCE_UUID INSTANCE_TOKEN LAYEROPS_WORKER_URL LAYEROPS_ORCHESTRATOR_URL SPIRE_URL WIREGUARD_PRIVATE_IP LAYEROPS_API_URL
  do
    [ -z "${!envvar}" ] && MISSING="$envvar $MISSING"
  done

  if [ ! -z "$MISSING" ]
  then
    echo "Missing following environment variables:"
    for var in $MISSING
    do
      echo "  $var"
    done
    exit 1
  fi
}

function curl_with_retry() {
  local RETRY_COUNT=0
  local RETRY_DELAY=5
  local MAX_RETRY_DELAY=60

  while true; do
    if curl "$@"; then
      return 0
    fi

    ((RETRY_COUNT++))
    echo "curl command failed (attempt #$RETRY_COUNT). Retrying in ${RETRY_DELAY}s..." >&2
    sleep $RETRY_DELAY

    # Exponential backoff with max delay cap
    RETRY_DELAY=$((RETRY_DELAY * 2))
    if [ $RETRY_DELAY -gt $MAX_RETRY_DELAY ]; then
      RETRY_DELAY=$MAX_RETRY_DELAY
    fi
  done
}

function _get_worker_version() {
  REMOTE_VERSION=$(curl_with_retry -s --max-time 10 "$LAYEROPS_WORKER_VERSION_CHECK")
  if [ -z "$REMOTE_VERSION" ]; then
    echo "1.0.0"
    return
  fi

  echo "$REMOTE_VERSION"
}

function _setup_ssh() {
  # Set CUSTOM_SSH_USER if not already defined
  [ -z "$CUSTOM_SSH_USER" ] && CUSTOM_SSH_USER=dev

  # Create custom ssh user
  id $CUSTOM_SSH_USER > /dev/null 2>&1 || adduser -q --gecos "" --disabled-password --home /home/dev $CUSTOM_SSH_USER

  # Add custom ssh user to docker group because of "exec"
  adduser $CUSTOM_SSH_USER $DOCKER_GROUP

  # Add specific config to sshd_config for user dev
  SSHD_CONFIG=/etc/ssh/sshd_config

  # Add port 22 if it doesn't already exist (and not commented)
  if ! grep -q "^Port 22" $SSHD_CONFIG; then
    # Add Port 22 before any Match blocks
    if grep -q "^Match" $SSHD_CONFIG; then
      sed -i '/^Match/i Port 22' $SSHD_CONFIG
    else
      echo "Port 22" >> $SSHD_CONFIG
    fi
  fi

  # Add port 2222 if it doesn't already exist (and not commented)
  if ! grep -q "^Port 2222" $SSHD_CONFIG; then
    # Add Port 2222 before any Match blocks
    if grep -q "^Match" $SSHD_CONFIG; then
      sed -i '/^Match/i Port 2222' $SSHD_CONFIG
    else
      echo "Port 2222" >> $SSHD_CONFIG
    fi
  fi

  # Add SSH config if it doesn't already exist
  if ! grep -q "Match User dev" $SSHD_CONFIG; then
    cat >> $SSHD_CONFIG <<EOF

Match User dev
    AuthorizedKeysCommand /bin/cat $LAYEROPS_DATA_DIR/ssh/dev_authorized_keys
    AuthorizedKeysCommandUser root

Match User dev LocalPort 22
    DenyUsers dev
EOF
    # Reload sshd to apply changes
    systemctl reload sshd || systemctl reload ssh
  fi
}

function _init() {

  # Install required packages
  while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 1; done;
  while fuser /var/lib/apt/lists/lock >/dev/null 2>&1; do sleep 1; done;
  apt-get update && apt-get install -y --no-install-recommends ca-certificates curl coreutils iptables jq rsyslog uuid-runtime wireguard wireguard-tools || exit 1

  # Set instance signature
  INSTANCE_SIGNATURE=$(uuidgen)
  INSTANCE_INIT_REQUEST=$(cat << EOF
{
  "instanceUuid": "${INSTANCE_UUID}",
  "instanceAccessToken": "${INSTANCE_TOKEN}",
  "signature": "${INSTANCE_SIGNATURE}",
  "environmentGroupUuid": "${ENVIRONMENT_GROUP_UUID}"
}
EOF
)
  curl_with_retry --fail-with-body -A $CURL_USER_AGENT -X POST -H "Content-Type: application/json" -d "$INSTANCE_INIT_REQUEST" ${LAYEROPS_ORCHESTRATOR_URL}/instances/init
  [ "$?" -ne "0" ] && exit 1

  # Create layerops user
  id $LAYEROPS_USER > /dev/null 2>&1 || adduser -q --gecos "" --disabled-password --home $LAYEROPS_HOME_DIR $LAYEROPS_USER
  mkdir -p $LAYEROPS_HOME_DIR/.ssh
  touch $LAYEROPS_HOME_DIR/.ssh/authorized_keys
  [ -z "$ADDITIONAL_SSH_KEYS_URL" ] || curl_with_retry -H "User-Agent: NimeOps-UA" $ADDITIONAL_SSH_KEYS_URL >> $LAYEROPS_HOME_DIR/.ssh/authorized_keys

  # Create mandatory folders
  mkdir -p \
    $WIREGUARD_CONFIG_DIR \
    $LAYEROPS_ETC_DIR \
    $LAYEROPS_BIN_DIR \
    $DOCKER_DATA_DIR \
    $SPIRE_CONFIG_DIR \
    $SPIRE_AGENT_DATA_DIR \
    $LAYEROPS_DATA_DIR
  touch \
    $LAYEROPS_ETC_DEFAULT_FILE \
    $SPIRE_AGENT_CONFIG_FILE \
    $WIREGUARD_CONFIG_FILE \
    $WIREGUARD_TEMPLATE_FILE
  chmod 700 $WIREGUARD_CONFIG_DIR $LAYEROPS_ETC_DIR $SPIRE_CONFIG_DIR

  # Install NVIDIA drivers if needed:
  if [ "$LXC_USE_NVIDIA_GPU" == "true" ]
  then
    NVIDIA_INSTALLED=$(nvidia-smi > /dev/null 2>&1 && echo 1 || echo 0)
    if [ $NVIDIA_INSTALLED -eq 0 ]
    then
      apt-get install -y --no-install-recommends ubuntu-drivers-common
      add-apt-repository -y ppa:graphics-drivers/ppa
      apt-get install -y --no-install-recommends $(nvidia-detector)
    fi
  fi

  # Install Docker
  mkdir -p /etc/apt/keyrings
  curl_with_retry -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
  chmod a+r /etc/apt/keyrings/docker.asc
  echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/$(. /etc/os-release && echo $ID) \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
    > /etc/apt/sources.list.d/docker.list
  apt-get update && apt-get install -y --no-install-recommends docker-ce docker-ce-cli
  adduser $LAYEROPS_USER $DOCKER_GROUP

  cat <<EOF > $DOCKER_DAEMON_FILE
{
  "data-root": "$DOCKER_DATA_DIR"
}
EOF

  # Setup SSH user and configuration
  _setup_ssh

  # Install Node_Exporter
  id $NODE_EXPORTER_USERGROUP > /dev/null 2>&1 || adduser --system --group --shell /bin/false --no-create-home $NODE_EXPORTER_USERGROUP
  curl_with_retry -fsSL https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz \
    | tar -zxvf - -C ${LOCAL_BIN_DIR} --strip-components=1 node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter
  chown $NODE_EXPORTER_USERGROUP:$NODE_EXPORTER_USERGROUP ${LOCAL_BIN_DIR}/node_exporter
  cat <<EOF > $NODE_EXPORTER_SYSTEMD_FILE
[Unit]
Description=Node Exporter
Requires=network-online.target wg-quick@${WIREGUARD_INTERFACE}.service
After=network-online.target wg-quick@${WIREGUARD_INTERFACE}.service

[Service]
User=node_exporter
Group=node_exporter
ExecStart=${LOCAL_BIN_DIR}/node_exporter --web.listen-address=${WIREGUARD_PRIVATE_IP}:${NODE_EXPORTER_BIND_PORT}

[Install]
WantedBy=multi-user.target
EOF

  # Set sudo access to layerops user
  cat > $SUDO_FILE <<EOF
# Group rules for layerops
%layerops ALL=(ALL) NOPASSWD: /usr/bin/wg-quick, /usr/bin/wg, $WIREGUARD_QUICK_RELOAD_PATH
%layerops ALL=(ALL) NOPASSWD: $SPIRE_AGENT_LAUNCH_SCRIPT
EOF

  [[ "${ENVIRONMENT_MODE:-DEFAULT}" == "DEV" ]] && cat > $SUDO_FILE <<EOF
# Group rules for layerops
%layerops ALL=(ALL) NOPASSWD: ALL
EOF

  # Create volumes if available
  FS_TYPE=ext4
  FSTAB_OPTIONS=defaults
  FSTAB_FILE=/etc/fstab

  DEVICE=$(lsblk --json | jq -r '[.blockdevices[] | select(.type == "disk") | select(.children == null)]  | first | .name')
  if [[ ! -z "$DEVICE" && "$DEVICE" != "null" ]]
  then
    DISK=/dev/$DEVICE

    pvcreate $DISK
    vgcreate $VGNAME $DISK
    LV_SIZE=$(vgs --reportformat=json --units B $VGNAME | jq -r '.report[].vg[].vg_free' | tr '<' ' ')
    lvcreate -L $LV_SIZE -n $LVNAME $VGNAME

    PARTITION=/dev/${VGNAME}/${LVNAME}
    mkfs.$FS_TYPE -F $PARTITION

    echo "MOUNT $LAYEROPS_DATA_DIR on $PARTITION"
    FSTAB_LINE="$PARTITION $LAYEROPS_DATA_DIR $FS_TYPE $FSTAB_OPTIONS 0 2"
    grep -q "^$PARTITION" $FSTAB_FILE && sed "s=^${PARTITION}.*=$FSTAB_LINE=" -i $FSTAB_FILE || echo "$FSTAB_LINE" >>  $FSTAB_FILE

    mount $LAYEROPS_DATA_DIR
  fi

  # Enable ip forwarding (for docker network)
  grep -qxF 'net.ipv4.ip_forward = 1' /etc/sysctl.conf || echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
  sysctl -p /etc/sysctl.conf

  # Init Wireguard:
  WIREGUARD_PRIVATE_KEY=$(wg genkey)
  WIREGUARD_PUBLIC_KEY=$(echo "$WIREGUARD_PRIVATE_KEY" | wg pubkey)
  WIREGUARD_PORT=51820
  cat > $WIREGUARD_CONFIG_FILE <<EOF
[Interface]
PrivateKey = $WIREGUARD_PRIVATE_KEY
Address = $WIREGUARD_PRIVATE_IP/32
ListenPort = $WIREGUARD_PORT
PostUp = ip -4 route add $WIREGUARD_SUBNET dev $WIREGUARD_INTERFACE
PostDown = ip -4 route del $WIREGUARD_SUBNET dev $WIREGUARD_INTERFACE
Table = off
EOF
  cat > $WIREGUARD_TEMPLATE_FILE <<EOF
[Interface]
PrivateKey = $WIREGUARD_PRIVATE_KEY
Address = $WIREGUARD_PRIVATE_IP/32
MTU = $WIREGUARD_MTU
#ListenPort = $WIREGUARD_PORT
ListenPort = 0 # set random default listen port
PostUp = ip -4 route add $WIREGUARD_SUBNET dev $WIREGUARD_INTERFACE
PostDown = ip -4 route del $WIREGUARD_SUBNET dev $WIREGUARD_INTERFACE
Table = off

{{ range .WireguardPeers }}{{ if ne .PublicIp "" }}
# {{ .Role }} - {{ or .InstanceUuid "" }}
[Peer]
PublicKey = {{ .WireguardPublicKey }}
AllowedIPs = {{ .PrivateIp }}/32{{ if eq .Role "server" }},$WIREGUARD_SUBNET{{ end }}
PersistentKeepalive = 5
{{ if and (eq .Role "server") (ne .PublicIp "") }}Endpoint = {{ .PublicIp }}:{{ .WireguardPublicPort }}{{ end }}
{{ if and (eq .Role "lb") (ne .PublicIp "") }}Endpoint = {{ .PublicIp }}:$WIREGUARD_PORT{{ end }}

{{ end }}{{ end }}
EOF

  cat > $WIREGUARD_QUICK_RELOAD_PATH <<EOF
#!/bin/bash
#/usr/bin/wg-quick up \$1 > /dev/null 2>&1 || /usr/bin/wg syncconf \$1 <(exec /usr/bin/wg-quick strip \$1)
systemctl reload wg-quick@\$1
EOF
  chmod 755 $WIREGUARD_QUICK_RELOAD_PATH

cat > $WIREGUARD_RELOAD_PATH <<EOF
#!/bin/bash
sudo $WIREGUARD_QUICK_RELOAD_PATH $WIREGUARD_INTERFACE
EOF
  chmod 755 $WIREGUARD_RELOAD_PATH

  # Install Spire agent
  cd /tmp
  curl_with_retry -s -N -L $SPIRE_URL | tar xz || exit 1
  mv spire*/bin/spire-agent $SPIRE_AGENT_PATH
  chmod 755 $SPIRE_AGENT_PATH

  # Configure Spire agent
  # Configure Spire agent
  BOOTSTRAP_SETTINGS="insecure_bootstrap = true"
  REBOOSTRAP_MODE_SETTINGS="rebootstrap_mode = \"auto\""
  [[ $SPIRE_TRUST_BUNDLE_URL == https://* ]] && BOOTSTRAP_SETTINGS="trust_bundle_url = \"$SPIRE_TRUST_BUNDLE_URL\"" || REBOOSTRAP_MODE_SETTINGS=""
  cat > $SPIRE_AGENT_CONFIG_FILE <<EOF
agent {
    data_dir = "$SPIRE_AGENT_DATA_DIR"
    log_level = "DEBUG"
    trust_domain = "$SPIRE_TRUST_DOMAIN"
    server_address = "$SPIRE_SERVER_IP"
    server_port = $SPIRE_BIND_PORT
    $BOOTSTRAP_SETTINGS
    $REBOOSTRAP_MODE_SETTINGS
}

plugins {
   KeyManager "disk" {
        plugin_data {
            directory = "$SPIRE_AGENT_DATA_DIR"
        }
    }

    NodeAttestor "http_challenge" {
        plugin_data {
            hostname = "$WIREGUARD_PRIVATE_IP"
            port = $SPIRE_HTTP_CHALLENGE_PORT
        }
    }

    WorkloadAttestor "unix" {
        plugin_data {}
    }
    WorkloadAttestor "docker" {
        plugin_data {}
    }
}
EOF

  cat > $SPIRE_AGENT_SYSTEMD_FILE <<EOF
[Unit]
Description=Spire Agent
Requires=network-online.target wg-quick@${WIREGUARD_INTERFACE}.service
After=network-online.target wg-quick@${WIREGUARD_INTERFACE}.service

[Service]
User=$LAYEROPS_USER
Group=$LAYEROPS_GROUP

TimeoutStartSec=0
ExecStartPre=+setcap 'cap_net_bind_service=+ep' $SPIRE_AGENT_PATH
ExecStart=$SPIRE_AGENT_PATH run -config $SPIRE_AGENT_CONFIG_FILE
ExecStop=/bin/kill -9 \$MAINPID

Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

  cat > $SPIRE_AGENT_LAUNCH_SCRIPT <<EOF
#!/bin/bash
if [ "\$1" == "reset" ]
then
  systemctl stop spire-agent
  rm -f $SPIRE_AGENT_DATA_DIR/*
fi
systemctl enable --now spire-agent
EOF
  chmod 755 $SPIRE_AGENT_LAUNCH_SCRIPT

  # Install layerops worker
  REMOTE_VERSION=$(_get_worker_version)
  DOWNLOAD_URL="${LAYEROPS_WORKER_URL}/worker-${REMOTE_VERSION}"
  echo "Downloading worker from $DOWNLOAD_URL..."
  curl_with_retry -s -N -L -o $LAYEROPS_WORKER_PATH $DOWNLOAD_URL
  chmod 755 $LAYEROPS_WORKER_PATH

  # Setup layerops config
  export INSTANCE_CPU_CORES=$(cat /proc/cpuinfo | grep -i "^processor" | wc -l)

  INSTANCE_CPU_MHZ_TOTAL=0
  for CORE_MHZ in $(cat /proc/cpuinfo | grep -i "^cpu MHz" | awk -F": " '{print $2}')
  do
    INSTANCE_CPU_MHZ_TOTAL=$(echo $INSTANCE_CPU_MHZ_TOTAL $CORE_MHZ | awk '{print $1 + $2}')
  done
  export INSTANCE_CPU_MHZ=$(echo $INSTANCE_CPU_MHZ_TOTAL $INSTANCE_CPU_CORES | awk '{print int(($1 / $2) * 1000 + 0.5) / 1000}')

  INSTANCE_MEMORY_KB=$(cat /proc/meminfo  |grep MemTotal: | awk '{print $2}')
  export INSTANCE_MEMORY_GB=$(echo $INSTANCE_MEMORY_KB 1048576 | awk '{print int(($1 / $2) * 1000 + 0.5) / 1000}')

  INSTANCE_STORAGE_KB=$(df /opt/ | awk 'NR>1 {print $2}')
  export INSTANCE_STORAGE_GB=$(echo $INSTANCE_STORAGE_KB 1048576 | awk '{print int(($1 / $2) * 1000 + 0.5) / 1000}')

cat > $LAYEROPS_ETC_DEFAULT_FILE <<EOF
WIREGUARD_RELOAD_PATH=$WIREGUARD_RELOAD_PATH
WIREGUARD_CONFIG_FILE=$WIREGUARD_CONFIG_FILE
WIREGUARD_TEMPLATE_FILE=$WIREGUARD_TEMPLATE_FILE
WIREGUARD_PUBLIC_KEY=$WIREGUARD_PUBLIC_KEY
SPIRE_AGENT_LAUNCH_SCRIPT=$SPIRE_AGENT_LAUNCH_SCRIPT
SPIRE_TRUST_DOMAIN=$SPIRE_TRUST_DOMAIN
INSTANCE_CPU_CORES=$INSTANCE_CPU_CORES
INSTANCE_CPU_MHZ=$INSTANCE_CPU_MHZ
INSTANCE_MEMORY_GB=$INSTANCE_MEMORY_GB
INSTANCE_STORAGE_GB=$INSTANCE_STORAGE_GB
LAYEROPS_DATA_DIR=$LAYEROPS_DATA_DIR
STATS_PORT=$STATS_PORT
STATS_CACHE_TTL=$STATS_CACHE_TTL
ROLE=instance
API_ORCHESTRATOR=$LAYEROPS_ORCHESTRATOR_URL
LAYEROPS_WORKER_URL=$LAYEROPS_WORKER_URL
LAYEROPS_WORKER_VERSION_CHECK=$LAYEROPS_WORKER_VERSION_CHECK
ENVIRONMENT_GROUP_UUID=$ENVIRONMENT_GROUP_UUID
INSTANCE_UUID=$INSTANCE_UUID
SIGNATURE=$INSTANCE_SIGNATURE
STATS=true
EOF

  cat > $LAYEROPS_WORKER_SYSTEMD_FILE <<EOF
[Unit]
Description=Launch layerops worker v%i
After=network.target

[Service]
Type=simple
User=$LAYEROPS_USER
Group=$LAYEROPS_GROUP
EnvironmentFile=-$LAYEROPS_ETC_DEFAULT_FILE
ExecStart=$LAYEROPS_WORKER_PATH --version %i

KillMode=mixed
TimeoutStopSec=1800

Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

  cat > $LAYEROPS_WORKER_UPDATE_SYSTEMD_FILE <<EOF
[Unit]
Description=Check for LayerOps Worker updates

[Service]
Type=oneshot
ExecStart=$LAYEROPS_WORKER_UPDATE_SCRIPT
EnvironmentFile=-$LAYEROPS_ETC_DEFAULT_FILE
EOF

  cat > $LAYEROPS_WORKER_UPDATE_SYSTEMD_TIMER_FILE <<EOF
[Unit]
Description=Run LayerOps updater every 5 minutes

[Timer]
OnBootSec=1min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
EOF

  # Set ownership for /opt/layerops directory
  chown -R $LAYEROPS_USER:$LAYEROPS_GROUP $LAYEROPS_HOME_DIR $WIREGUARD_CONFIG_DIR $LAYEROPS_ETC_DIR $SPIRE_CONFIG_DIR $LAYEROPS_DATA_DIR
  chown root:root $DOCKER_DATA_DIR

  # Enable and start layerops worker
  systemctl daemon-reload
  systemctl enable --now \
    wg-quick@${WIREGUARD_INTERFACE} \
    layerops-worker@${REMOTE_VERSION} \
    layerops-worker-update.timer \
    node_exporter
  systemctl restart docker
}


function _clean() {
  # Remove layerops sudo config
  rm -f $SUDO_FILE

  # Stop services
  systemctl disable --now \
    layerops-worker@${REMOTE_VERSION} \
    layerops-worker-update.timer \
    spire-agent \
    node_exporter \
    wg-quick@${WIREGUARD_INTERFACE}
  rm -f \
    $LAYEROPS_WORKER_SYSTEMD_FILE \
    $SPIRE_AGENT_SYSTEMD_FILE
  systemctl daemon-reload

  # Delete layerops user
  id $LAYEROPS_USER > /dev/null 2>&1 && userdel $LAYEROPS_USER

  # Uninstall Wireguard
  apt-get remove -y wireguard wireguard-tools

  # Clean files
  rm -fR \
    $LAYEROPS_HOME_DIR \
    $LAYEROPS_WORKER_PATH \
    $WIREGUARD_CONFIG_FILE \
    $WIREGUARD_TEMPLATE_FILE \
    $LAYEROPS_ETC_DIR
}

if [[ "$#" -eq 0 ]]; then
  usage
fi

case "$1" in
  init)
    check_envvars
    _init
    ;;
  clean)
    _clean;;
  *)
    usage;;
esac
