#!/bin/bash

# Script to deploy a self-hosted version of Transitive using Docker Compose.

BLACK="\033[30m"
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[34m"
PINK="\033[35m"
CYAN="\033[36m"
WHITE="\033[37m"
NORMAL="\033[0;39m"

printStep() {
  printf "\n$GREEN$@$NORMAL\n"
}

printWarn() {
  printf "\n$YELLOW$@$NORMAL\n"
}

# Generate a secret, using /dev/random as randomness source
getSecret() {
  length=$([[ -z $1 ]] && echo 24 || echo $1)
  cat /dev/random | od -An -x -N 1024 | tr -d '\n ' | cut -c -$length
}


DIR=~/transitive
# We need to create some folders to ensure the right owner, including for the
# generated certs (see certs/generate.sh).
mkdir -p $DIR/certs;
mkdir -p $DIR/db;

# For dev: create a folder read by cloud-app where capabilities can be updated live
mkdir -p /tmp/caps;

cd $DIR;

if [[ -e $DIR/.env ]]; then
  printWarn "There already exists a .env file. Won't reset. If you'd like to reset your deployment, please remove $DIR/db and rerun.";

else

  printStep "Generating .env file"

  curl -sO https://raw.githubusercontent.com/transitiverobotics/transitive/refs/heads/main/cloud/sample.env

  # find all env vars in sample.env that are secrets:
  VARS=$(grep -oP '(?<!\w)\$\{?\K[A-Z_][A-Z0-9_]+' sample.env | sort -u | grep _SECRET)

  # generate secrets for all these env vars
  for n in $VARS; do
    echo Generating secret for $n;
    export $n=$(getSecret 20)
  done

  RANDOM_SUBDOMAIN=$(getSecret 10)

  # fill in ENV vars in sample.env to generate .env
  cat sample.env | while read -r L; do
    if [[ $L =~ ^# ]] then
      # print comments as is
      echo $L;
    else
      # interpret all other lines
      eval echo $L;
    fi;
  done > .env

  echo $DIR/.env written;
fi;


printStep "Fetching docker-compose.yaml from GitHub repo"
curl -sO https://raw.githubusercontent.com/transitiverobotics/transitive/refs/heads/main/cloud/docker-compose.yaml

# Detect Docker Compose (standalone or plugin)
if ( docker-compose > /dev/null 2>&1 ); then
  function compose() {
    docker-compose $@
  }
elif ( docker compose > /dev/null 2>&1 ); then
  function compose() {
    docker compose $@
  }
else
  echo "** Error: you don't appear to have Docker Compose installed."
  echo "Please see https://docs.docker.com/compose/install/."
  exit 1;
fi;


printStep "Checking that Avahi (mDNS) is installed";

if ( ! dpkg -l avahi-daemon > /dev/null ); then
  echo "You don't have avahi-daemon installed. Please run"
  echo " sudo apt-get install -y avahi-daemon"
  echo "and then try again."
  exit 2;
fi;


printStep "Pulling Docker images";

# Pull images from dockerhub
compose pull

printStep "Starting deployment";

# Start it!
compose up -d

printStep "Verify local mDNS is working";

# Verify that local subdomains work
if (getent hosts ${RANDOM_SUBDOMAIN}.${HOSTNAME}.local > /dev/null); then
  echo "mDNS verification successful"
  echo "All done! 🚀"
  echo -n "Now "
else
  echo "⚠️  mDNS verification failed! Please follow the instructions in"
  echo "https://github.com/transitiverobotics/transitive/blob/main/cloud/tools/mDNS/README.md"
  echo ""
  echo -n "Then "
fi;

# Get active password from .env file (in case it already existed)
ACTIVE_PASSWORD=$(cat $DIR/.env | grep TR_PASS | cut -d '=' -f 2)

# Let the user know next steps
echo "go to http://portal.${HOSTNAME}.local and log in using these credentials:"
echo "  user: admin"
echo "  password: $ACTIVE_PASSWORD"
echo ""
echo "If you want to stop the servive again, run \"cd $DIR && docker compose down\"."
echo "If you want to use capabilities available from transitiverobotics.com, then edit .env to set your username and JWT secret from your transitiverobotics.com account in TR_BILLING_USER and TR_BILLING_SECRET respectively."
echo "To update your deployment, just rerun this command."
