#!/usr/bin/env bash

REQUIRED_CONFIGS+=("APP")
REQUIRED_CONFIGS+=("BUILD_HOST")
REQUIRED_CONFIGS+=("BUILD_USER")
REQUIRED_CONFIGS+=("BUILD_AT")
OPTIONAL_CONFIGS+=("FROM")
OPTIONAL_CONFIGS+=("WITH")
OPTIONAL_CONFIGS+=("TO")
OPTIONAL_CONFIGS+=("REBAR_CONFIG")

TO="${TO:=$(get_latest_commit)}"

set_build_hosts

run() {
  authorize_hosts
  authorize_release_store_on_build_host
  if [[ -n "$WITH" ]]; then
    [[ "$RELEASE_CMD" = "mix" ]] && local _release_type="*" || local _release_type="release"
    validate_release_is_in_store "$_release_type" $WITH # we can skip init_app_remotely and pushing to remote if release does not exist
    if [[ $? -ne 0 ]]; then
      hint_message "You can build appups also with the --from=<git-tag-or-revision> option\nif the release is not in your release store"; exit 2
    fi
    # push current state
    init_app_remotely
    git_push
    git_reset_remote
    git_clean_remote
  elif [[ -n "$FROM" ]]; then
    # push current state
    init_app_remotely
    git_push
    git_reset_remote
    git_clean_remote
    # checkout old version
    git_checkout_remote $FROM
    # build old release
    erlang_get_and_update_deps
    erlang_clean_compile
    erlang_generate_release
    [[ "$RELEASE_CMD" = "rebar" ]] && rename_release_add_version
    [[ "$RELEASE_CMD" = "mix" ]] && __detect_remote_release_dir && __detect_remote_release_version
    OLD_RELEASE_VERSION=${RELEASE_VERSION}
  else
    error_message "no old version specified"; exit 2
  fi

  # checkout new version
  git_checkout_remote $TO
  # build new release
  erlang_get_and_update_deps
  erlang_clean_compile

  if [[ -n "$WITH" ]] && [[ "$RELEASE_CMD" != "rebar" ]]; then
    # when generating upgrades with `mix release` (exrm) the old
    # release must be uploaded before generating the release.
    # `erlang_generate_release` generates the upgrade then automatically
    RELEASE_DIR="${DELIVER_TO}/rel/${APP}"
    local _release_destination_path="$(dirname $RELEASE_DIR)"
    [[ "$RELEASE_FILE" =~ upgrade\.tar\.gz$ ]] && _release_destination_path="${_release_destination_path%%/}/${APP}"
    upload_release_archive "$_release_destination_path" "$RELEASE_FILE" "$WITH"
    remote_extract_release_archive "$WITH" "$(dirname $RELEASE_DIR)"
    if [[ "$RELEASE_FILE" =~ upgrade\.tar\.gz$ ]]; then
      status "Removing old releases which were included in upgrade package"
      __remote "
        [ -f ~/.profile ] && source ~/.profile
        set -e
        cd \"$(dirname $RELEASE_DIR)/${APP}/releases\" $SILENCE
        for release_dir in \$(ls -1); do
          [[ \"\$release_dir\" != \"$WITH\"  ]] && [[ -n \"\$release_dir\" ]] && [[ -d \"\$release_dir\" ]] && echo \"removing \$release_dir\" $SILENCE && rm -rf \"\$release_dir\" || :
        done
      "
    fi
    __detect_remote_release_dir
    __detect_remote_release_version
    OLD_RELEASE_VERSION=${RELEASE_VERSION}
  fi


  if [[ "$RELEASE_CMD" = "relx" ]]; then
    relx_generate_relup
  else
    erlang_generate_release
  fi

  if [[ -n "$WITH" ]] && [[ "$RELEASE_CMD" = "rebar" ]]; then
    __detect_remote_release_dir
    # backup new release
    rename_release_add_version "new"
    NEW_RELEASE_VERSION=$RELEASE_VERSION;
    OLD_RELEASE_VERSION="$WITH"
    # upload and extract old release
    upload_release_archive "$(dirname $RELEASE_DIR)" "${APP}_${WITH}.release.tar.gz" "$WITH"
    remote_extract_release_archive "$WITH" "$(dirname $RELEASE_DIR)"
    # rename old release
    rename_release_add_version "old" "$WITH"
    # restore new release
    rename_release_remove_version $NEW_RELEASE_VERSION
  fi

  # generate default appups
  [[ "$RELEASE_CMD" = "rebar" ]] && rebar_generate_appup $OLD_RELEASE_VERSION
  # overwrite default appups with custom appups
  [[ "$RELEASE_CMD" = "rebar" ]] && copy_appups_from_release_store_to_build_host $OLD_RELEASE_VERSION
  # generate upgrade package and copy it to release store
  if [[ "$RELEASE_CMD" = "relx" ]]; then
    erlang_archive_release
  elif [[ "$RELEASE_CMD" = "mix" ]]; then
    remove_built_release_archive "$OLD_RELEASE_VERSION"
    RELEASE_VERSION="" # redetect new version
    __detect_remote_release_version
  else
    rebar_generate_upgrade $OLD_RELEASE_VERSION
  fi
  copy_release_to_release_store "upgrade"
}




