#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"

git_build_app_repo() {
  verify_app_name "$1"
  APP="$1"; REV="$2"

  # clean up after ourselves
  TMP_WORK_DIR=$(mktemp -d)
  trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN

  # git clone
  chmod 755 $TMP_WORK_DIR
  unset GIT_DIR GIT_WORK_TREE
  pushd $TMP_WORK_DIR > /dev/null
  git clone -q "$DOKKU_ROOT/$APP" "$TMP_WORK_DIR" &> /dev/null
  git config advice.detachedHead false
  git checkout "$REV" &> /dev/null
  git submodule update --init --recursive &> /dev/null
  find -name .git -prune -exec rm -rf {} \; > /dev/null

  if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]]; then
    plugn trigger pre-receive-app "$APP" "dockerfile" "$TMP_WORK_DIR" "$REV"
    dokku receive "$APP" "dockerfile" "$TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/"
  else
    plugn trigger pre-receive-app "$APP" "herokuish" "$TMP_WORK_DIR" "$REV"
    dokku receive "$APP" "herokuish" "$TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/"
  fi
}

case "$1" in
  git-hook)
    APP=$2

    while read -r oldrev newrev refname; do
      # Only run this script for the master branch. You can remove this
      # if block if you wish to run it for others as well.
      if [[ $refname = "refs/heads/master" ]]; then
        # broken out into plugin so we might support other methods to receive an app
        plugn trigger receive-app $APP $newrev
      else
        if test -f "$PLUGIN_PATH"/enabled/*/receive-branch; then
          plugn trigger receive-branch $APP $newrev $refname
        else
          echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master."
          echo $'\e[1G\e[K'"-----> for example, try 'git push <dokku> ${refname/refs\/heads\/}:master'"
        fi
      fi
    done
    ;;

  git-upload-pack)
    APP="$(echo $2 | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
    plugn trigger git-pre-pull $APP
    cat | git-upload-pack "$DOKKU_ROOT/$APP"
    plugn trigger git-post-pull $APP
    ;;

  git-build)
    APP="$2"; APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock"
    APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..."
    [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG"

    shift 1
    flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@"
    ;;

  git-build-locked)
    APP="$2"
    if [[ $# -ge 3 ]]; then
      REF="$3"
    else
      REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master")
    fi
    git_build_app_repo $APP $REF
    ;;

  git-*)
    APP="$(echo $2 | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')"
    APP_PATH=$DOKKU_ROOT/$APP

    if [[ $1 == "git-receive-pack" && ! -d "$APP_PATH/refs" ]]; then
      git init --bare $APP_PATH > /dev/null
      PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive"
      cat > $PRERECEIVE_HOOK <<EOF
#!/usr/bin/env bash
set -e; set -o pipefail;

cat | DOKKU_ROOT="$DOKKU_ROOT" dokku git-hook $APP
EOF
      chmod +x $PRERECEIVE_HOOK
    fi

    if [[ $1 == "git-receive-pack" ]]; then
      args="$1 '$APP_PATH'"
    else
      args=$*
    fi
    git-shell -c "$args"
    ;;

  help | git:help)
    echo -n ""
    ;;

  *)
    exit $DOKKU_NOT_IMPLEMENTED_EXIT
    ;;

esac
