#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# SHELLDOC-IGNORE


this="${BASH_SOURCE-$0}"
thisdir=$(cd -P -- "$(dirname -- "${this}")" >/dev/null && pwd -P)

pushd "${thisdir}/.." >/dev/null || exit 1

if [[ ! -d precommit ]]; then
  echo "ERROR: Unsure about directory structure."
  exit 1
fi

#shellcheck source=SCRIPTDIR/../precommit/src/main/shell/core.d/00-yetuslib.sh
. precommit/src/main/shell/core.d/00-yetuslib.sh

BINDIR=$(yetus_abs "${thisdir}")
BASEDIR=$(yetus_abs "${BINDIR}/..")

PARAMS=("$@")

echo_and_redirect()
{
  declare logfile=$1
  shift

  # to the screen
  echo "cd $(pwd)"
  echo "${*} > ${logfile} 2>&1"

  yetus_run_and_redirect "${logfile}" "${@}"
}

set_defaults()
{
  # Where our artifacts are located
  ARTIFACTS_DIR=${BASEDIR}/yetus-dist/target/artifacts

  # deploy to maven staging repo
  DEPLOY=false

  GPG=$(command -v gpg)
  GPGAGENT=$(command -v gpg-agent)

  LOGDIR="/tmp/build-log"

  PUBKEYFILE="https://downloads.apache.org/yetus/KEYS"

  SIGN=false
}


big_console_header()
{
  declare text="$*"
  declare spacing=$(( (75+${#text}) /2 ))

  printf '\n\n'
  echo "============================================================================"
  echo "============================================================================"
  printf '%*s\n'  ${spacing} "${text}"
  echo "============================================================================"
  echo "============================================================================"
  printf '\n\n'
}

startgpgagent()
{
  if [[ "${SIGN}" = true ]]; then
    if [[ -n "${GPGAGENT}" && -z "${GPG_AGENT_INFO}" ]]; then
      echo "starting gpg agent"
      echo "default-cache-ttl 36000" > "${LOGDIR}/gpgagent.conf"
      echo "max-cache-ttl 36000" >> "${LOGDIR}/gpgagent.conf"
      # shellcheck disable=2046
      eval $("${GPGAGENT}" --daemon \
        --options "${LOGDIR}/gpgagent.conf" \
        --log-file="${LOGDIR}/create-release-gpgagent.log")
      GPGAGENTPID=$(pgrep "${GPGAGENT}")
      GPG_AGENT_INFO="$HOME/.gnupg/S.gpg-agent:$GPGAGENTPID:1"
      export GPG_AGENT_INFO
    fi

    if [[ -n "${GPG_AGENT_INFO}" ]]; then
      echo "Warming the gpg-agent cache prior to calling maven"
      # warm the agent's cache:
      touch "${LOGDIR}/warm"
      "${GPG}" --use-agent --armor --output "${LOGDIR}/warm.asc" --detach-sig "${LOGDIR}/warm"
      rm "${LOGDIR}/warm.asc" "${LOGDIR}/warm"
    else
      SIGN=false
      yetus_error "ERROR: Unable to launch or acquire gpg-agent. Disable signing."
    fi
  fi
}

stopgpgagent()
{
  if [[ -n "${GPGAGENTPID}" ]]; then
    kill "${GPGAGENTPID}"
  fi
}

usage()
{
  yetus_add_option "--asfrelease" "Make an ASF release"
  yetus_add_option "--deploy" "Deploy Maven artifacts using ~/.m2/settings.xml"
  yetus_add_option "--logdir=[path]" "Path to store logs"
  yetus_add_option "--sign" "Use .gnupg dir to sign the artifacts and jars"
  yetus_generic_columnprinter "${YETUS_OPTION_USAGE[@]}"
  yetus_reset_usage
}

option_parse()
{
  declare i

  for i in "$@"; do
    case ${i} in
      --asfrelease)
        ASFRELEASE=true
        SIGN=true
        DEPLOY=true
      ;;
      --deploy)
        DEPLOY=true
      ;;
      --help)
        usage
        exit
      ;;
      --logdir=*)
        LOGDIR=${i#*=}
      ;;
      --sign)
        SIGN=true
      ;;
    esac
  done

  if [[ ! -d "${HOME}/.gnupg" ]]; then
    yetus_error "ERROR: No .gnupg dir. Disabling signing capability."
    SIGN=false
  fi

  if [[ "${SIGN}" = true ]]; then
    if [[ -n "${GPG_AGENT_INFO}" ]]; then
      echo "NOTE: Using existing gpg-agent. If the default-cache-ttl"
      echo "is set to less than ~20 mins, maven commands will fail."
    elif [[ -z "${GPGAGENT}" ]]; then
      yetus_error "ERROR: No gpg-agent. Disabling signing capability."
      SIGN=false
    fi
  fi

  if [[ "${DEPLOY}" = true && ! -f "${HOME}/.m2/settings.xml" ]]; then
    yetus_error "ERROR: No ~/.m2/settings.xml file, cannot deploy Maven artifacts."
    exit 1
  fi

  if [[ "${ASFRELEASE}" = true ]]; then
    if [[ "${SIGN}" = false ]]; then
      yetus_error "ERROR: --asfrelease requires --sign. Exiting."
      exit 1
    fi
  fi

  mkdir -p "${LOGDIR}"

}

makearelease()
{
  declare target="install"

  if [[ "${DEPLOY}" = true ]]; then
    target="deploy"
  fi

  if [[ "${SIGN}" = true ]]; then
    signflags+=("-Psign" "-Dgpg.useagent=true" "-Dgpg.executable=gpg")
  fi

  if [[ "${ASFRELEASE}" = true ]]; then
    signflags+=("-Papache-release")
  fi

  # let's start at the root
  pushd "${BASEDIR}" >/dev/null || exit 1

  big_console_header "Cleaning the Source Tree"

  # git clean to clear any remnants from previous build
  echo_and_redirect "${LOGDIR}/git_clean.log" git clean -xdf

  echo_and_redirect "${LOGDIR}/mvn_clean.log" mvn --batch-mode clean

  big_console_header "Apache RAT Check"

  # Create RAT report
  echo_and_redirect "${LOGDIR}/mvn_apache_rat.log" mvn --batch-mode apache-rat:check

  big_console_header "Maven Build and Install"

  echo_and_redirect "${LOGDIR}/mvn_${target}.log" \
    mvn --batch-mode "${target}" \
      "${signflags[@]}" \
      -DskipTests

  big_console_header "Maven Site"

  echo_and_redirect "${LOGDIR}/mvn_site.log" \
    mvn --batch-mode site site:stage </dev/null
}

signartifacts()
{
  declare i
  declare ret

  if [[ "${SIGN}" = false ]]; then
    echo ""
    echo "Remember to sign the artifacts before staging them on the open"
    echo ""
    return
  fi

  big_console_header "Signing the release"

  pushd "${ARTIFACTS_DIR}" > /dev/null || exit 1
  for i in *; do
    gpg --use-agent --armor --output "${i}.asc" --detach-sig "${i}"
    gpg --print-mds "${i}" >"${i}".mds
    sha512sum --tag "${i}" > "${i}.sha512"
  done

  popd > /dev/null || exit 1

  if [[ "${ASFRELEASE}" = true ]]; then
    echo "Fetching the Apache Yetus KEYS file..."
    curl -L "${PUBKEYFILE}" -o "${BASEDIR}/target/KEYS"
    gpg --import --trustdb "${BASEDIR}/target/testkeysdb" "${BASEDIR}/target/KEYS"
    for i in "${ARTIFACTS_DIR}"/*gz; do
      gpg --verify --trustdb "${BASEDIR}/target/testkeysdb" \
        "${i}.asc" "${i}"
      ret=$?
      if [[ ${ret} != 0 ]]; then
        yetus_error "ERROR: GPG key is not present in ${PUBKEYFILE}."
        yetus_error "ERROR: This MUST be fixed. Exiting."
        exit 1
      fi
    done
  fi
}

set_defaults

option_parse "${PARAMS[@]}"

startgpgagent

makearelease
releaseret=$?

signartifacts

stopgpgagent

if [[ ${releaseret} == 0 ]]; then
  echo
  echo "Congratulations, you have successfully built the release"
  echo "artifacts for Apache Yetus ${YETUS_VERSION}"
  echo
  echo "The artifacts for this run are available at ${ARTIFACTS_DIR}:"
  ls -1 "yetus-dist/target/artifacts"

  echo
fi
