#!/bin/bash

# locals
ENV="$(build/ec2/env-get)"
NAME="ponyfoo-$ENV"
KEYFILE="deploy/keys/$ENV"

# stack specific
NODE_VERSION="0.10"

# instance specific
REGION="us-east-1"
IMAGE_ID="ami-8caa1ce4"
INSTANCE_TYPE="t1.micro"
INSTANCE_USER="ubuntu"
SECURITY_GROUP="standard"
PLATFORM="ubuntu"
COUNT="1"

if ! hash jq 2>/dev/null ; then
  echo "You need to install jq\n\
  brew install jq"
  exit
fi

if [ ! -f ~/.aws/config ] ; then
  echo "You need to install awscli and configure it!\n\
  pip install awscli\n\
  aws configure\n"
  exit
fi

if [ -f $KEYFILE ] ; then
  echo "Key file already exists!"
  exit
fi

# directories
mkdir -p deploy/keys

# rsa key
ssh-keygen -t rsa -b 4096 -N "" -f $KEYFILE
aws ec2 import-key-pair --key-name $NAME --public-key-material file://$KEYFILE.pub

# launch instance
echo "Launching instance..."

RESOURCE_ID=$(aws ec2 run-instances \
  --image-id $IMAGE_ID \
  --instance-type $INSTANCE_TYPE \
  --count $COUNT \
  --key-name $NAME \
  --security-groups $SECURITY_GROUP | jq -r .Instances[0].InstanceId)

echo "$RESOURCE_ID: launched"

# tag instance
aws ec2 create-tags --resources $RESOURCE_ID --tag Key=Name,Value=$NAME
echo "$RESOURCE_ID: tagged $NAME"

# assign ip address
IP_ADDRESS=$(aws ec2 allocate-address | jq -r .PublicIp)
echo "$RESOURCE_ID: IP $IP_ADDRESS created"

aws ec2 associate-address --instance-id $RESOURCE_ID --public-ip $IP_ADDRESS
echo "$RESOURCE_ID: IP $IP_ADDRESS assigned to instance"

# wait on public dns

PUBLIC_DNS="null"
while [ "$PUBLIC_DNS" == "null" ]
do
  echo "$RESOURCE_ID: Polling for public DNS..."
  INSTANCE=$(aws ec2 describe-instances --instance-ids $RESOURCE_ID | jq .Reservations[0].Instances[0])
  PUBLIC_DNS=$(echo "$INSTANCE" | jq -r .PublicDnsName)
done

echo "$RESOURCE_ID: DNS is $PUBLIC_DNS"

echo $PUBLIC_DNS > $KEYFILE.dns
echo $RESOURCE_ID > $KEYFILE.id
echo $INSTANCE_USER > $KEYFILE.user
echo $IP_ADDRESS > $KEYFILE.ip

# wait on stable ssh connectivity
ATTEMPTS="0"
CONSECUTIVE="0"
while [ "$CONSECUTIVE" != "3" ]
do
  SUCCESS="1"
  while [ "$SUCCESS" != "0" ]
  do
    ATTEMPTS=$[$ATTEMPTS +1]
    echo "$RESOURCE_ID: Establishing ssh connection... ($ATTEMPTS)"
    sleep 10
    ssh -ttti $KEYFILE -o ConnectTimeout=10 -o StrictHostKeyChecking=no -q $INSTANCE_USER@$PUBLIC_DNS exit
    SUCCESS=$?
    if [ "$SUCCESS" != "0" ] ; then
      CONSECUTIVE="0"
    fi
  done
  CONSECUTIVE=$[$CONSECUTIVE +1]
  echo "$RESOURCE_ID: Establishing ssh connection... ($ATTEMPTS) passed ($CONSECUTIVE/3)!"
done

### setup

APP="~/apps/$ENV"
RSYNC="~/apps/.rsync/$ENV"
RSYNC_MAILTUBE="$RSYNC/mailtube"
RSYNC_REPO="$RSYNC/app"
RSYNC_CONFIG="$RSYNC/config"
NGINX_LOG="/var/log/nginx"

# jump into instance
ssh -ttti $KEYFILE -o StrictHostKeyChecking=no $INSTANCE_USER@$PUBLIC_DNS << EOF_INITIAL
  echo "stage: aptitude!"
  sudo apt-key update
  sudo apt-get update
  sudo apt-get install git make g++ graphicsmagick -y

  echo "stage: tcp tweaks"
  sudo sysctl -w net.ipv4.tcp_slow_start_after_idle=0

  echo "stage: forwarding!"
  cp /etc/sysctl.conf /tmp/
  echo "net.ipv4.ip_forward = 1" >> /tmp/sysctl.conf
  sudo cp /tmp/sysctl.conf /etc/
  sudo sysctl -p /etc/sysctl.conf

  echo "stage: forward port 80 to 8080"
  sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
  sudo iptables -A INPUT -p tcp -m tcp --sport 80 -j ACCEPT
  sudo iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
  sudo iptables-save

  echo "stage: expected directory structure"
  mkdir -p $APP
  mkdir -p $RSYNC_MAILTUBE
  mkdir -p $RSYNC_REPO
  mkdir -p $RSYNC_CONFIG

  sudo mkdir -p $NGINX_LOG
  sudo chown ubuntu $NGINX_LOG
  sudo chmod -R 755 $NGINX_LOG

  echo "stage: nvm"
  curl https://raw.githubusercontent.com/creationix/nvm/v0.15.0/install.sh | bash

  echo "stage: nginx"
  sudo apt-get install nginx -y
EOF_INITIAL

# jump into instance once again
ssh -ttti $KEYFILE -o StrictHostKeyChecking=no $INSTANCE_USER@$PUBLIC_DNS << EOF_NODE
  echo "stage: nodejs"
  nvm install $NODE_VERSION
  nvm alias default $NODE_VERSION
EOF_NODE

echo "Instance $RESOURCE_ID launched!"
