#!/bin/bash

if [ -z "$1" ]; then
   echo "ERROR: command is't defined"  >&2
   exit 1
fi

if [ -z "$2" ]; then
   echo "ERROR: name of the rails application isn't defined"  >&2
   exit 2
fi

method=$1
name=$2
cmd=$3

libexecdir=/usr/lib
datadir=$libexecdir
rootdir=$datadir/$name
confdir=$rootdir/config
cachedir=/var/cache/$name
logdir=$datadir/$name/log
tmpdir=/var/tmp/$name
[ -n $(id -u _$name 2>/dev/null) ] && user=_$name
if [ -z "$user" ]; then
   tmpdir=/var/tmp/$name
else
   if [[ "$user" = "$(whoami)" ]]; then
      tmpdir=$TMP/$name
   else
      tmpdir=$(su $user -c 'echo $TMP')/$name
   fi
fi

export RAILS_ENV=production
export RAKE_ENV=production

function setup {
   cd $rootdir
   echo "Work dir is '$rootdir'"

   echo "Processing rails application '$name' setup..."

   # Add the "$name" user and group
   getent group $name >/dev/null || groupadd -r $name
   getent passwd _$name >/dev/null || \
   useradd -r -g $name -d $rootdir -s /bin/bash -c "$name" _$name

   #validate postgresdb
   #%post_service postgresql

   mkdir -m 750 -p $tmpdir/pids $tmpdir/sockets $cachedir
   rm -f $rootdir/tmp
   rm -rf $tmpdir/cache
   ln -sf $tmpdir $rootdir/tmp
   ln -sf $cachedir $tmpdir/cache
   chown $user:$name $tmpdir
   chown $user:$name $cachedir

   # CONFDIR=/etc
   # alias bundle exec rake='bundle exec rake'

   if [ -z "$(psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$name'")" ]; then
      # create db users with postgres
      # echo "Please enter password for an admin of the $name server: "
      createuser $name -U postgres --createdb --createrole -w # -W
   fi

   # env
   echo "Renewing dependencies..."
   rm -f Gemfile.lock
   bundle > $logdir/bundle.log 2>&1 || return 3
   # bundle binstubs bundler --force
   # npm install

   # secret token used for cookie signing etc.
   if [ ! -f $datadir/$name/config/initializers/local_secret_token.rb ]; then
      echo "Initializing secret..."
      touch $datadir/$name/config/initializers/local_secret_token.rb
      chmod 0660 $datadir/$name/config/initializers/local_secret_token.rb
      chgrp $name $datadir/$name/config/initializers/local_secret_token.rb
      bundle exec rake security:generate_token >> $logdir/generators.log 2>&1 || return 4
      chmod 0640 $datadir/$name/config/initializers/local_secret_token.rb
   fi

   # encryption key used to encrypt DB contents
   # move the generated key file to /etc/$name/ so users back it up, symlink to it from ~$name
   if [ ! -e $datadir/$name/config/initializers/encryption_key.rb -a \
        ! -e $confdir/encryption_key.rb ]; then
      echo "Initializing encryption key..."
      touch $datadir/$name/config/initializers/encryption_key.rb
      chmod 0660 $datadir/$name/config/initializers/encryption_key.rb
      chgrp $name $datadir/$name/config/initializers/encryption_key.rb
      bundle exec rake security:generate_encryption_key >> $logdir/generators.log 2>&1 || return 5
      chmod 0640 $datadir/$name/config/initializers/encryption_key.rb
      mv $datadir/$name/config/initializers/encryption_key.rb $confdir/
   fi

   if [ ! -e $datadir/$name/config/initializers/encryption_key.rb -a \
          -e $confdir/encryption_key.rb ]; then
      echo "Initializing link to encryption key..."
      ln -s $confdir/encryption_key.rb $datadir/$name/config/initializers/
   fi

   if ! psql -U postgres -lqt | cut -d \| -f 1 | grep -qw ${name}_${RAILS_ENV}; then
      echo "Initializing database..."
      bundle exec rake db:create >> $logdir/db_setup.log 2>&1 || return 6
   fi

   echo "Checking migration and seeds..."
   # We need to run the db:migrate after the install transaction
   # always attempt to reencrypt after update in case new fields can be encrypted
   bundle exec rake db:migrate db:encrypt_all >> $logdir/db_setup.log 2>&1 || return 7
   bundle exec rake db:seed >> $logdir/db_setup.log 2>&1 || return 8

   echo "Generating API cache..."
   bundle exec rake apipie:cache:index >> $logdir/apipie_cache.log 2>&1 || return 9

   # -z "$(ls ./public/webpack/*.js 2>/dev/null)" -a \
   if [ -n "$(bundle exec rake -T 2>/dev/null |grep webpack:compile)" ]; then
      echo "Initializing webpack frontend..."
      bundle exec rake webpack:compile >> $logdir/webpack_compile.log 2>&1 || return 11
   fi

   # compile always
   if [ -n "$(bundle exec rake -T 2>/dev/null |grep assets:precompile)" ]; then
      echo "Initializing assets frontend..."
      bundle exec rake assets:precompile >> $logdir/assets_precompile.log 2>&1 || return 12
   fi

   echo "Cleaning..."
   bundle exec rake tmp:clear >> $logdir/tmp_clear.log 2>&1 || return 10

   # display password
   grep "Login credentials" /var/log/foreman/ -r | sed "s,.*:Log,Log," | tail -1

   chown $user:$name $logdir/*.log -R 2>/dev/null
   chown $user:$name $tmpdir -R 2>/dev/null
   chown $user:$name Gemfile.lock 2>/dev/null
}

function cleanup {
   echo "Cleaning up..."

   rm -rf $datadir/$name/tmp $tmpdir $cachedir $rootdir/Gemfile.lock
}

function mrproper {
   cd $rootdir
   echo "Work dir is '$rootdir'"

   echo "Trying stop service..."
   systemctl stop $name

   echo "Dropping DB..."
   DISABLE_DATABASE_ENVIRONMENT_CHECK=1 \
      bundle exec rake db:drop >> $logdir/db_setup.log 2>&1 || return 13

   cleanup

   cd $HOME
   echo "Try removing package..."
   apt-get remove $name <<< "y" >> $logdir/setup.log 2>&1 || return 14

   echo "MrPropering..."
   rm -rf $rootdir
   dropuser $name -U postgres
   groupdel -f $name
   userdel -rf _$name
}

function run {
   cd $rootdir
   echo "Running command '$@' in work dir '$rootdir'..."

   bundle exec "$@" 2>$logdir/run_errors.log || (
      rm -f Gemfile.lock
      bundle > $logdir/bundle.log 2>&1 || return 3
      bundle exec "$@" 2>$logdir/run_errors.log )
}

case "$method" in
   setup)
      setup
      ;;
   cleanup)
      cleanup
      ;;
   mrproper)
      mrproper
      ;;
   run)
      if [ -z "$cmd" ]; then
         echo "ERROR: command to run the rails application isn't defined"  >&2
         exit 13
      fi
      shift
      shift

      run "$@"
      ;;
esac

code=$?

if (( code != 0 )); then
   echo "Error code is: $code"
fi

exit $code
