#!/bin/bash

#> The nodeapp scriptlet will provision a space on your machine for a
#  node application to be deployed.  A directory is scaffolded using the
#  `githost` scriptlet and then a suitable node post-receive hook is created.
# 
#  Additionally, the node app scriptlet will also provision an upstart script
#  for the node application based on the currently specified version of node
#  (as per the ${APP_VERSIONS[node]} setting).
#
#  Finally, an nginx site configuration will be created for the application
#  to proxy to the application using nginx.
#
#  ### Example Usage
#
#  ```
#  nodeapp name port 
#  ```
#
#  ### Preparing your application
#
#  See: https://bitbucket.org/DamonOehlman/bashinate/wiki/prepping-nodeapps
#<

local APP_NAME=$1
local APP_PORT=${2-3000}

# TODO: how to intelligently configure, maybe use branch names from within the post-receive hook
local NODE_ENV=production
local NODE_HOME=/opt/local/node/${APP_VERSIONS[node]}
local USEREXISTS_NODE=$(userExists node)
local UPSTART_SCRIPT=/home/node/.init/$APP_NAME.conf
local ON_RECEIVE

# unshift the name and port
shift; shift

[[ $IS_ROOT ]] || abort "To provision a node app, you must have root permissions"

# ensure the application name is specified
[[ $APP_NAME ]] || abort "Provisioning a node application requires a name"

[[ -d $NODE_HOME ]] || abort "node version unknown, please specify using 'use node <version>'"

# create our custom post-receive hook logic
read -d '' ON_RECEIVE <<-SCRIPT
  # install node dependencies
  $NODE_HOME/bin/npm install

  # restart (or start if required) the service
  sudo -u node restart $APP_NAME || sudo -u node start $APP_NAME
SCRIPT

# initialise using the githost logic, but we will provide our own
# post receive hook logic
require githost apps/$APP_NAME $(echo "$ON_RECEIVE" | tr '\n' '\237')

# ensure the node user exists (add to the git group)
if [ ! $USEREXISTS_NODE ]; then
  log "creating node user"
  rm -rf /home/node
  useradd -m -d /home/node -G git node
fi

# upstart user jobs needed, let's test with the node user
require upstart-user-jobs node

# Create an upstart script for the node application
function upstartScript {
  cat <<UPSTART
# wait for the user-jobs signal to be emitted
start on user-jobs

# environment variables for the script
env NODE_PORT=$APP_PORT
env NODE_ENV=$NODE_ENV

# change into the correct directory and run the script
chdir /home/git/apps/$APP_NAME/master
exec $NODE_HOME/bin/node server.js

# respawn if it dies
respawn
UPSTART
}

# ensure the git user is allowed to run processes as node
cat << 'SCRIPT' > /etc/sudoers.d/git-as-node
# allow git to sudo the node user's service processes
git ALL=(node) NOPASSWD: /sbin/start, /sbin/stop, /sbin/restart
SCRIPT

# set the required permissions on the sudoer script
chmod 0440 /etc/sudoers.d/git-as-node

# create the upstart script
upstartScript > $UPSTART_SCRIPT

# update own and set executable
chown node:node $UPSTART_SCRIPT
chmod a+x $UPSTART_SCRIPT

# tell them the git remote add line for copy and paste friendliness
log "nodeapp $APP_NAME provisioned ok, add a git remote using the following:"
log "git remote add deploy git@`hostname`:apps/$APP_NAME.git"