#!/bin/bash

set -eu

# Only GNU getopt supports long options. OS X comes bundled with the BSD getopt
# brew install gnu-getopt to get the GNU getopt on OS X
[[ $(uname -s) == "Darwin" ]] && GNU_GETOPT="/usr/local/opt/gnu-getopt/bin/getopt" || GNU_GETOPT="getopt"
readonly GNU_GETOPT

args=$(${GNU_GETOPT} -o "" -l "revision:,output:" -n "$0" -- "$@")
eval set -- "${args}"

readonly SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

commitish="HEAD"
bundle_file=""

while true; do
    case "$1" in
    --revision) commitish="$2"; shift 2;;
    --output) bundle_file="$2"; shift 2;;
    --) break;;
    *) echo "Unknown option $1"; exit 1;;
    esac
done

readonly TMPDIR=${TMPDIR:-/tmp} # why is this not set on mint?

if ! $(cd "${SOURCE_DIR}" && git diff --exit-code >/dev/null); then
    echo "You have local changes, stash or commit them to proceed"
    exit 1
fi

if [[ "$(node --version)" != "v6.9.2" ]]; then
    echo "This script requires node 6.9.2"
    exit 1
fi

version=$(cd "${SOURCE_DIR}" && git rev-parse "${commitish}")
bundle_dir=$(mktemp -d -t box 2>/dev/null || mktemp -d box-XXXXXXXXXX --tmpdir=$TMPDIR)
[[ -z "$bundle_file" ]] && bundle_file="${TMPDIR}/box-${version}.tar.gz"

chmod "o+rx,g+rx" "${bundle_dir}" # otherwise extracted tarball director won't be readable by others/group
echo "Checking out code [${version}] into ${bundle_dir}"
(cd "${SOURCE_DIR}" && git archive --format=tar ${version} | (cd "${bundle_dir}" && tar xf -))

if diff "${TMPDIR}/boxtarball.cache/npm-shrinkwrap.json.all" "${bundle_dir}/npm-shrinkwrap.json" >/dev/null 2>&1; then
    echo "Reusing dev modules from cache"
    cp -r "${TMPDIR}/boxtarball.cache/node_modules-all/." "${bundle_dir}/node_modules"
else
    echo "Installing modules with dev dependencies"
    (cd "${bundle_dir}" && npm install)

    echo "Caching dev dependencies"
    mkdir -p "${TMPDIR}/boxtarball.cache/node_modules-all"
    rsync -a --delete "${bundle_dir}/node_modules/" "${TMPDIR}/boxtarball.cache/node_modules-all/"
    cp "${bundle_dir}/npm-shrinkwrap.json" "${TMPDIR}/boxtarball.cache/npm-shrinkwrap.json.all"
fi

echo "Building webadmin assets"
(cd "${bundle_dir}" && gulp)

echo "Remove intermediate files required at build-time only"
rm -rf "${bundle_dir}/node_modules/"
rm -rf "${bundle_dir}/webadmin/src"
rm -rf "${bundle_dir}/gulpfile.js"

if diff "${TMPDIR}/boxtarball.cache/npm-shrinkwrap.json.prod" "${bundle_dir}/npm-shrinkwrap.json" >/dev/null 2>&1; then
    echo "Reusing prod modules from cache"
    cp -r "${TMPDIR}/boxtarball.cache/node_modules-prod/." "${bundle_dir}/node_modules"
else
    echo "Installing modules for production"
    (cd "${bundle_dir}" && npm install --production --no-optional)

    echo "Caching prod dependencies"
    mkdir -p "${TMPDIR}/boxtarball.cache/node_modules-prod"
    rsync -a --delete "${bundle_dir}/node_modules/" "${TMPDIR}/boxtarball.cache/node_modules-prod/"
    cp "${bundle_dir}/npm-shrinkwrap.json" "${TMPDIR}/boxtarball.cache/npm-shrinkwrap.json.prod"
fi

echo "Create final tarball"
(cd "${bundle_dir}" && tar czf "${bundle_file}" .)
echo "Cleaning up ${bundle_dir}"
rm -rf "${bundle_dir}"

echo "Tarball saved at ${bundle_file}"

