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

# Prerequisites:
# Install a JavaScript runtime - e.g. `sudo apt install node-js`
# Install Ruby 3.3.5 using RVM for all users:
#   (note the use of sudo, which puts installers into /usr/local/rvm, instead of the user's home directory):
#   sudo gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
#   curl -L https://get.rvm.io | sudo bash -s stable
#   sudo rvm install 3.3.5
#   sudo rvm use --default 3.3.5 # Run as both ubuntu and flask
###
### DO NOT CONTINUE UNTIL BOTH YOUR USER AND `flask` ARE ABLE TO RELIABLY RUN `rvm`
### AND `which rvm` RETURNS `/usr/local/rvm/bin/rvm`
### AND ruby -v RETURNS 3.3.5
###

if [ ! -z "$4" ]; then
  echo "Service names:   $SERVICE-blue, $SERVICE-green"
  echo "Port numbers:    $PORT1, $PORT2"
  echo "Install paths:   $INSTALL_PATH/$APP_NAME-blue, $INSTALL_PATH/$APP_NAME-green"
  echo "Domain:          $DOMAIN"
  echo "Download:        git clone git@gitlab.com:SatSenseLtd/frontend.git"
else
  echo "Must provide 4 params:    Service name    |     App name (path)   |    Parent directory   |       Domain       | Port"
  echo "e.g.  ./frontend.bash    staging-frontend          frontend          /var/www/staging    staging.satsense.com    7000"
  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/apache2/sites-available/$SERVICE.conf"
echo "sudo rm /etc/apache2/sites-enabled/$SERVICE.conf"
echo "sudo rm -rf $INSTALL_PATH/$APP_NAME*"
echo "sudo systemctl daemon-reload"
echo "sudo service apache2 reload"
echo ""

read -r -p "Type Y to continue, or anything else to exit: " input
if [ $input != 'Y' ]; then
  echo "Exiting"
  exit
fi

INDEX=0
for colour in blue green
do
    install_path="${INSTALL_PATH}/${APP_NAME}-${colour}"
    printf "\n\nInstalling to $install_path\n\n"

    sudo git clone https://gitlab.com/SatSenseLtd/frontend.git $install_path
    cd $install_path

    printf "\n\nChanging owner\n\n"
    sudo chown -hR $USER:$USER $install_path
    sudo chown -hR $USER:$USER $install_path
    printf "\n\nInstalling gems...\n\n"
    bundle install

    # Create .env if blue, symlink to the blue one if green
    if [ "$colour" = "green"  ]; then
        sudo cp $INSTALL_PATH/$APP_NAME-blue/.env $INSTALL_PATH/$APP_NAME-green/.env
        printf "\n\nCopied .env blue to .env green.  We will symlink this later, for for now we want control of its file permissions.\n\n"
    else
        sudo touch "${install_path}/.env"
        printf "Suggested content for .env file:\n\nAPI_URI='https://api.satsense.com'\nSERVER_API_KEY=\nPORT=$PORT1\nWORKERS=8\nENV=production\nFRONTEND_DATABASE_USERNAME=\nFRONTEND_DATABASE_PASSWORD=\nFRONTEND_DATABASE_PORT=\n\n"
        read -r -p "Modify the ${install_path}.env and provide necessary variables, then type Y to continue, or anything else to exit: " input
        if [ $input != 'Y' ]; then
            echo "Exiting"
            exit
        fi

        RAILS_ENV=production rails db:create
        RAILS_ENV=production rails db:migrate
    fi
    
    printf "\n\nChanging owner again\n\n"
    sudo chown -hR $USER:$USER $install_path
    sudo chown -hR $USER:$USER $install_path

    # Master credentials
    sudo rm  $install_path/config/credentials.yml.enc 
    sudo rm  $install_path/config/master.key

    if [ "$colour" = "green"  ]; then
      sudo cp $INSTALL_PATH/$APP_NAME-blue/config/credentials.yml.enc $INSTALL_PATH/$APP_NAME-green/config/credentials.yml.enc
      sudo cp $INSTALL_PATH/$APP_NAME-blue/config/master.key $INSTALL_PATH/$APP_NAME-green/config/master.key
      printf "Copying credentials.yml.enc and master.key from blue to green"
    else
      printf "Creating credentials files"
      RAILS_ENV=production rails credentials:edit
    fi

    printf "\n\nChanging owner again\n\n"
    sudo chown -hR $USER:$USER $install_path
    sudo chown -hR $USER:$USER $install_path

    printf "\n\nCreating puma directory"
    sudo mkdir $install_path/tmp/puma

    printf "\n\nCompiling assets"
    cd $install_path
    RAILS_ENV=production rails assets:precompile

    if [ "$colour" = "green"  ]; then
        printf "\n\nRemoving local .env and credentials files, and symlinking to blue to avoid duplication, now we've compiled assets."
        sudo rm $INSTALL_PATH/$APP_NAME-green/.env
        sudo rm $INSTALL_PATH/$APP_NAME-green/config/credentials.yml.enc
        sudo rm $INSTALL_PATH/$APP_NAME-green/config/master.key

        sudo ln -s $INSTALL_PATH/$APP_NAME-blue/.env $INSTALL_PATH/$APP_NAME-green/.env
        sudo ln -s $INSTALL_PATH/$APP_NAME-blue/config/credentials.yml.enc $INSTALL_PATH/$APP_NAME-green/config/credentials.yml.enc
        sudo ln -s $INSTALL_PATH/$APP_NAME-blue/config/master.key $INSTALL_PATH/$APP_NAME-green/config/master.key
    fi

    printf "\n\nChanging owner to flask\n\n"
    sudo chown -hR flask:www-data $install_path
    sudo chown -hR flask:www-data $install_path

    # Services
    SERVICE_NAME="${SERVICE}-${colour}"
    printf "\n\nCreating $SERVICE_NAME service\n\n"
    sudo touch /etc/systemd/system/$SERVICE_NAME.service
    sudo chmod 664 /etc/systemd/system/$SERVICE_NAME.service

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

[Service]
User=flask
Type=simple
WorkingDirectory=$install_path
ExecStart=/usr/local/rvm/rubies/ruby-3.3.5/bin/bundle exec rails s -e production
Environment="RAILS_ENV=production"
Environment="PATH=/usr/local/rvm/gems/ruby-3.3.5/bin:/usr/local/rvm/gems/ruby-3.3.5@global/bin:/usr/local/rvm/rubies/ruby-3.3.5/bin:/usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
Environment="GEM_HOME=/usr/local/rvm/gems/ruby-3.3.5"
TimeoutSec=30
RestartSec=15
Restart=always
KillMode=process
KillSignal=SIGQUIT

[Install]
WantedBy = multi-user.target

EOT

    sudo systemctl daemon-reload

    sudo systemctl start $SERVICE_NAME
    systemctl status $SERVICE_NAME
    sudo systemctl stop $SERVICE_NAME
    sudo systemctl enable $SERVICE_NAME

    sudo systemctl start $SERVICE_NAME

    INDEX=$(expr $INDEX + 1)

done


# Apache
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 $DOMAIN
ServerAlias $DOMAIN
DocumentRoot $INSTALL_PATH/$APP_NAME-blue/public

# rewrite to https
RewriteEngine on
RewriteCond %{SERVER_NAME} =$DOMAIN
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

<VirtualHost *:443>
ServerName $DOMAIN
ServerAlias $DOMAIN
DocumentRoot $INSTALL_PATH/$APP_NAME-blue/public

<Proxy balancer://$APP_NAME>
    BalancerMember unix://$INSTALL_PATH/$APP_NAME-blue/tmp/puma/puma.sock|http://localhost:$PORT1/
    BalancerMember unix://$INSTALL_PATH/$APP_NAME-green/tmp/puma/puma.sock|http://localhost:$PORT2/
</Proxy>

<Location /assets>
  ProxyPass !
</Location>
<Location /icon.png>
  ProxyPass !
</Location>
<Location /favicon.ico>
  ProxyPass !
</Location>
<Location /system>
  ProxyPass !
</Location>

ProxyPass / balancer://$APP_NAME/
ProxyPassReverse / balancer://$APP_NAME/

# 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

</VirtualHost>
EOT

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

sudo service apache2 reload

# Certbot
sudo certbot --apache

echo "Done.  TAKE NOTE OF THE ENCRYPTION KEYS OUTPUT ABOVE AND RECORD THEM SOMEWHERE SAFE."
echo "This should have released a version of the app.  However, releases using cap ENV deploy will release to the base directory - modify the apache hostfile and systemd processes to point there if you're going to use cap for deployments, and then you can delete unused files in the parent directory for cleanup."