#!/usr/bin/env bash
# ======================================================================
#
# API CLIENT :: API REQUEST TO IML CI SERVER
#
# ----------------------------------------------------------------------
# 2020-07-23  v1.0  <axel.hahn@iml.unibe.ch>  first lines
# 2020-07-29  v1.1  <axel.hahn@iml.unibe.ch>  check "/" in branch; check http status 200 
# 2021-03-29  v1.2  <axel.hahn@iml.unibe.ch>  support slashes in branch names
# ======================================================================

# ----------------------------------------------------------------------
# CONFIG
# ----------------------------------------------------------------------

line="----------------------------------------------------------------------"
# LOG_FILE=/tmp/`basename $0`-last.log
# exec > >(tee -a ${LOG_FILE} )
# exec 2> >(tee -a ${LOG_FILE} >&2)

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

function showhelp(){
echo "
SYNTAX:
  -a ACTION     set name of an action
  -b BRANCH     set custom branch to access, i.e. origin/feature-123
  -p PROJECT    project name in the ci server; overrides env variable IMLCI_PROJECT
  -s SECRET     API secret for the given project; overrides env variable IMLCI_API_SECRET
  -u URL        URL of iml ci server without trailing /; overrides env variable IMLCI_URL

ACTION:
   ... without given project and secret
     projects   show projects

   ... with project and secret
     buildinfo [branch]
                show infos about what happens on build
     build [branch]
                execute build
     phases     show status of phases

EXAMPLES:
  `basename $0` -u https://ci.example.com -a projects
  `basename $0` -u https://ci.example.com -p myproject -s 12345678 -a buildinfo
  `basename $0` -u https://ci.example.com -p myproject -s 12345678 -a build
"
}


function makeRequest(){

  local apiMethod=$1
  local apiRequest=$2
  local secret=$3

  local outfile=$( mktemp )

  echo $line
  echo $apiMethod ${apiHost}${apiRequest}
  echo $line

  if [ ! -z "$secret" ]; then

    # --- date in http format
    LANG=en_EN
    # export TZ=GMT
    apiTS=`date "+%a, %d %b %Y %H:%M:%S %Z"`


# --- generate data to hash: method + uri + timestamp; delimited with line break
data="${apiMethod}
${apiRequest}
${apiTS}
"

    # generate hash - split in 2 commands (piping "cut" sends additional line break)
    myHash=`echo -n "$data" | openssl sha1 -hmac "${secret}" | cut -f 2 -d" "`
    myHash=`echo -n "$myHash" | base64`

    curl -i \
      -H "Accept: application/json" -H "Content-Type: application/json" \
      -H "Date: ${apiTS}" \
      -H "Authorization: demo-bash-client:${myHash}" \
      -X $apiMethod \
      ${IMLCI_URL}${apiRequest} | tee -a $outfile
  else
    curl -i \
      -H "Accept: application/json" -H "Content-Type: application/json" \
      -X $apiMethod \
      ${IMLCI_URL}${apiRequest} | tee -a $outfile
  fi

  grep "^HTTP\/" $outfile | head -1 | grep " 200 " >/dev/null
  local rccurl=$?

  rm -f $outfile
  if [ $rccurl -ne 0 ]; then
    echo
    echo "ERROR: API request failed. CURL request did not get respond status code 200."
    exit 4
  fi
}


# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

echo
echo ===== API CALL TO IML CI SERVER :: `date` =====
echo

if  [ $# -lt 1 ]; then
  showhelp
  exit 1
fi

while getopts "a:b:u:p:s:" option; do 
case ${option} in
  a)
    apiAction=$OPTARG
    ;;
  b)
    branch=$OPTARG
    ;;
  u)
    export IMLCI_URL=$OPTARG
    ;;
  p)
    export IMLCI_PROJECT=$OPTARG
    ;;
  s)
    export IMLCI_API_SECRET=$OPTARG
    ;;
  *)
    echo ERROR: invalid option [${option}]
    exit 2
esac
done

echo Params: $*
echo "IMLCI_URL = $IMLCI_URL"
echo "IMLCI_PROJECT = $IMLCI_PROJECT"
echo "IMLCI_API_SECRET = $IMLCI_API_SECRET"
echo

# task-4364: slashes are supported now
# echo $branch | grep '/.*/.*' >/dev/null && ( echo "WARNING: Do NOT use a branch containing a slash [/] in the name"; echo )


echo ACTION: $apiAction
case $apiAction in

  # --- projects is an access without autorization
  "projects")
    makeRequest GET  /api/v1/projects
    ;;

  # --- access WITH autorization only
  "build")
    makeRequest POST /api/v1/project/$IMLCI_PROJECT/build/$branch "$IMLCI_API_SECRET"
    ;;
  "buildinfo")
    makeRequest GET  /api/v1/project/$IMLCI_PROJECT/build/$branch "$IMLCI_API_SECRET"
    ;;
  "phases")
    makeRequest GET  /api/v1/project/$IMLCI_PROJECT/phases   "$IMLCI_API_SECRET"
    ;;
  *)
    echo "ERROR: unknown action [$apiAction]"
    exit 3
esac

rc=$?
echo
echo $line
date
echo rc=$rc

exit $rc
