#!/bin/bash

####################################################################
#
#  Rather than manually running `npm publish` for each package, run
#  this script which will check for some common mistakes and then
#  publish all packages to npm.
#
####################################################################

# Make sure the latest repo info is available.
git fetch;
if [[ $? -ne 0 ]]; then exit 1; fi;

# Colors
B="\e[1m"
R="\e[31m"
Y="\e[33m"
X="\e[0m"

# Extract useful information.
GITBRANCH=$(git branch -v 2> /dev/null | sed '/^[^*]/d');
GITBRANCHNAME=$(echo "$GITBRANCH" | sed 's/* \([A-Za-z0-9_\-]*\).*/\1/');
GITBRANCHSYNC=$(echo "$GITBRANCH" | sed 's/* [^[]*.\([^]]*\).*/\1/');
GITTAG=$(git tag -l --points-at HEAD)
RELAY_V=$(node -p -e "require('$(dirname $0)/../package.json').version")

# Function to confirm weird things before continuing.
confirm () {
  printf "\n$1\n  ${Y}Continue?${X} "
  read -p "(y|N) " yn
  [[ "$yn" != "y" ]] && exit 1
}

error () {
  printf "\n${R}${1}${X}\n"
  exit 1
}

# Check if master is checked out
if [ "$GITBRANCHNAME" != "master" ]; then
  confirm "Git not on ${B}master${X} but ${B}${GITBRANCHNAME}${X}."
fi

# Check if branch is synced with remote
if [ "$GITBRANCHSYNC" != "" ]; then
  confirm "Git not up to date but $GITBRANCHSYNC."
fi

# Check if this is a tagged commit.
if [ "$GITTAG" == "" ]; then
  confirm "Git commit does not have a version tag.\n  To fix: ${B}git tag 'v$RELAY_V' && git push --tags${X}"
elif [ "v$RELAY_V" != "$GITTAG" ]; then
  confirm "Top level Relay ${B}v${RELAY_V}${X} doesn't match git tag ${B}${GITTAG}${X}.";
fi

# Check that build has already run.
DIST_DIR=$(dirname $0)/../dist/
if [ ! -d "$DIST_DIR" ]; then
  error "The ${B}dist/${X}${R} directory does not exist, run ${B}npm run build${X}${R} to create it."
fi

# Check that npm version matches for every package
pushd "$DIST_DIR" > /dev/null
for PACKAGE in *; do
  if [ -d "$PACKAGE" ]; then
    PACKAGE_V=$(node -p -e "require('./$PACKAGE/package.json').version")
    if [ "v$PACKAGE_V" != "v$RELAY_V" ]; then
      confirm "$PACKAGE ${B}v${PACKAGE_V}${X} doesn't match Relay ${B}v${RELAY_V}${X}.";
    fi
  fi
done

# Just to be safe, don't let publish happen unless we're really sure.
if [ "$1" == "--shipit" ]; then
  SHIPIT=true
  printf "\nActually publishing to NPM.\n"
else
  printf "\nNot actually publishing, just illustrating. Pass ${B}--shipit${X} to publish.\n"
fi

# It's business time.
for PACKAGE in *; do
  if [ -d "$PACKAGE" ]; then
    PACKAGE_V=$(node -p -e "require('./$PACKAGE/package.json').version")
    IS_PRERELEASE=$(sed -n '/[0-9]-[a-zA-Z]/p' <<< $PACKAGE_V)
    TAG_ARG=$([[ $IS_PRERELEASE != "" ]] && echo '--tag dev')
    COMMAND="cd $PACKAGE && npm publish $TAG_ARG"
    printf "\n# $COMMAND\n"
    if [ "$SHIPIT" == "true" ]; then
      bash -c "$COMMAND"
    fi
  fi
done
popd > /dev/null
