#!/bin/bash

# Place this file in /home/satsense/installers/ and make it executable
# Then run 
#           ./api.bash $SERVICE $PORT1 $INSTALL_DIRECTORY
# e.g.      ./api.bash staging-api 5555 /var/www/staging/api

# NOTE: $PORT2 will be automatically generated by adding 1 to the value provided for $PORT1

SERVICE=$1
PORT1=$2
PORT2=$(($PORT1+1))
INSTALL_PATH=$3
TIMESTAMP=$(/bin/date +"%Y%m%d_%H%M%S")

if [ ! -z "$3" ]; then
  echo "Service names: $SERVICE-blue, $SERVICE-green"
  echo "Port numbers: $PORT1, $PORT2"
  echo "Install path: $INSTALL_PATH"
else
  echo "Must provide 3 params:    Service name    |     Port number   |    Path"
  echo "e.g.  ./api.bash          staging-api              5555        /var/www/staging/api"
  exit
fi

printf "\n\nTo revert everything this script is about to do, run the following commands:\n\n"

echo "sudo rm /etc/systemd/system/$SERVICE-blue.service"
echo "sudo rm /etc/systemd/system/$SERVICE-green.service"
echo "sudo rm /etc/systemd/system/$SERVICE-celery.service"
echo "sudo rm /etc/apache2/sites-available/$SERVICE.conf"
echo "sudo rm /etc/apache2/sites-enabled/$SERVICE.conf"
echo "sudo rm -rf $INSTALL_PATH"
echo "sudo systemctl daemon-reload"
echo "sudo service apache2 reload"
echo ""

printf "Using directory $TIMESTAMP\n\n"
read -r -p "Type Y to continue, ctrl+c to exit: " input
if [ $input != 'Y' ]; then
  echo "Exiting"
  exit
fi

# Create directories
sudo mkdir -p $INSTALL_PATH
cd $INSTALL_PATH

sudo mkdir log/
sudo chown flask:www-data log/

sudo mkdir log/flask
sudo chown flask:flask log/flask/

sudo mkdir log/gunicorn
sudo chown flask:flask log/gunicorn/

sudo mkdir app_home/
sudo chown flask:flask app_home/

sudo mkdir app_home/migrations/
sudo chown flask:flask app_home/migrations/

sudo mkdir virtual_environments/
sudo chown flask:flask virtual_environments/

# Create virtual environment
sudo -i -u flask /usr/bin/python3.9 -m venv $INSTALL_PATH/virtual_environments/venv

# Download artifacts
sudo -i -u flask /home/flask/releases/api/download_artifacts.bash main $TIMESTAMP

# Install
sudo -i -u flask cp /home/flask/releases/api/$TIMESTAMP/dist/api/app.py $INSTALL_PATH/app_home
sudo -i -u flask cp /home/flask/releases/api/$TIMESTAMP/dist/api/config.yml $INSTALL_PATH/app_home
sudo -i -u flask cp /home/flask/releases/api/$TIMESTAMP/dist/api/gunicorn_config.py $INSTALL_PATH/app_home
sudo -i -u flask cp /home/flask/releases/api/$TIMESTAMP/dist/api/routes.py $INSTALL_PATH/app_home
sudo -i -u flask cp /home/flask/releases/api/$TIMESTAMP/dist/api/setup.py $INSTALL_PATH/app_home
sudo -i -u flask cp -r /home/flask/releases/api/$TIMESTAMP/dist/api/main $INSTALL_PATH/app_home
sudo -i -u flask cp -r /home/flask/releases/api/$TIMESTAMP/dist/api/migrations $INSTALL_PATH/app_home

pip="${INSTALL_PATH}/virtual_environments/venv/bin/pip"

sudo -i -u flask $pip install -r /home/flask/releases/api/$TIMESTAMP/dist/api/requirements/production.txt

printf "\n\nInstalling API .whl package\n\n"
sudo mkdir $INSTALL_PATH/tmp
sudo cp -r /home/flask/releases/api/$TIMESTAMP/dist/api $INSTALL_PATH/tmp/
sudo -i -u flask $pip install $INSTALL_PATH/tmp/api/api*.whl
sudo rm -rf $INSTALL_PATH/tmp

sudo -i -u flask $pip install gunicorn

# Config
sudo -i -u flask tee -a $INSTALL_PATH/app_home/.env > /dev/null <<EOT
ENV=production
EOT

# Create services
# Main API Services
INDEX=0
for service in $SERVICE-blue $SERVICE-green
do
  sudo touch /etc/systemd/system/$service.service
  sudo chmod 664 /etc/systemd/system/$service.service

  sudo tee -a /etc/systemd/system/$service.service > /dev/null <<EOT
[Unit]
Description = $service
After = network.target

[Service]
User=flask
WorkingDirectory=$INSTALL_PATH/app_home
ExecStart=$INSTALL_PATH/virtual_environments/venv/bin/gunicorn -b localhost:$(($PORT1+$INDEX)) -w 4 app:app
Restart=always

[Install]
WantedBy = multi-user.target
EOT

  sudo systemctl daemon-reload

  sudo systemctl start $service
  systemctl status $service
  sudo systemctl stop $service
  sudo systemctl enable $service

  sudo systemctl start $service

  INDEX=$(expr $INDEX + 1)
done

# Celery Service
sudo touch /etc/systemd/system/$SERVICE-celery.service
sudo chmod 664 /etc/systemd/system/$SERVICE-celery.service

sudo tee -a /etc/systemd/system/$SERVICE-celery.service > /dev/null <<EOT
[Unit]
Description = $SERVICE-celery
After = network.target

[Service]
Type=simple
User=flask
Group=flask
WorkingDirectory=$INSTALL_PATH/app_home/main/services/satbots/scripts/importer
ExecStart=/bin/sh -c '$INSTALL_PATH/virtual_environments/venv/bin/celery -A tasks worker'
Restart=always

[Install]
WantedBy = multi-user.target
EOT
sudo systemctl daemon-reload
sudo systemctl start $SERVICE-celery
systemctl status $SERVICE-celery
sudo systemctl stop $SERVICE-celery
sudo systemctl enable $SERVICE-celery

sudo systemctl start $SERVICE-celery

# Apache vhost
printf "\n\nCreating Apache VirtualHost at /etc/apache2/sites-available/$SERVICE.conf\n\n"
sudo tee -a /etc/apache2/sites-available/$SERVICE.conf > /dev/null <<EOT
<VirtualHost *:80>
ServerName $SERVICE.localhost
ServerAlias $DOMAIN.localhost
DocumentRoot $INSTALL_PATH

<Proxy balancer://$SERVICE>
    BalancerMember http://localhost:$PORT1
    BalancerMember http://localhost:$PORT2
</Proxy>

# flask proxy
ProxyPreserveHost On
ProxyPass /static !
ProxyPass /error !
ProxyPass /tiles !
ProxyPass / balancer://$SERVICE/
ProxyPassReverse / balancer://$SERVICE/

# logs
ErrorLog $INSTALL_PATH/log/error.log
CustomLog $INSTALL_PATH/log/requests.log combined

# headers:
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains"
Header always set X-Frame-Options "deny"
Header always set X-Xss-Protection "1; mode=block"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "no-referrer"
Header always edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict

# Error Documents
ErrorDocument 503 /error/503.html
</VirtualHost>
EOT

sudo ln -s /etc/apache2/sites-available/$SERVICE.conf /etc/apache2/sites-enabled/$SERVICE.conf

sudo service apache2 reload

echo "App available to run at at $SERVICE.localhost"
printf "\n\nNow edit the $INSTALL_PATH/app_home/.env file with the necessary config and restart the services.\n\n"
echo "sudo vi $INSTALL_PATH/app_home/.env"
echo "sudo service $SERVICE-blue restart"
echo "sudo service $SERVICE-green restart"
echo "sudo service $SERVICE-celery restart"
