#!/bin/bash

set -a

#----------------------------
# Color table
# Black       0;30     Dark Gray     1;30
# Blue        0;34     Light Blue    1;34
# Green       0;32     Light Green   1;32
# Cyan        0;36     Light Cyan    1;36
# Red         0;31     Light Red     1;31
# Purple      0;35     Light Purple  1;35
# Brown       0;33     Yellow        1;33
# Light Gray  0;37     White         1;37
# No Color    0
#----------------------------
CBlack='\e[0;30m'
CDarkGray='\e[1;30m'
CBlue='\e[0;34m'
CLightBlue='\e[1;34m'
CGreen='\e[0;32m'
CLightGreen='\e[1;32m'
CCyan='\e[0;36m'
CLightCyan='\e[1;36m'
CRed='\e[0;31m'
CLightRed='\e[1;31m'
CPurple='\e[0;35m'
CLightPurple='\e[1;35m'
CBrown='\e[0;33m'
CYellow='\e[1;33m'
CGray='\e[0;37m'
CWhite='\e[1;37m'
CNone='\e[0m'

set +a

#----------------------------
# Echo a colored string to tty and tee-append it to a file without color codes
# Parameters:
#  $1 - string to echo
#  $2 - log filename
#  $3 - if "y" create a new file.
function echo_and_tee()
{
  if [ "$3" = "y" ]; then
    echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >"$2"
  else
    echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >>"$2"
  fi
}

#----------------------------
function _set_path_variables()
{
  # Set useful path variables
  set -a

  #-- get desired distribution and architecture
  [[ "$DISTRO"      = "" ]] && DISTRO=$(lsb_release -is | sed -e 's/\(.*\)/\L\1/')
  [[ "$DISTRO_NAME" = "" ]] && DISTRO_NAME=$(lsb_release -cs | sed -e 's/\(.*\)/\L\1/')
  [[ "$ARCHITECTURE" = "" ]] && ARCHITECTURE=$(dpkg --print-architecture)

  REPO_DIR="$TDE_DIR/$CFG_GIT_DIR"
  if [ "${USE_GIT_WORKTREES}" = "y" ]; then
    REPOS_DIR="$TDE_DIR/$CFG_GIT_DIR/repos"
    WORKTREES_DIR="$TDE_DIR/$CFG_GIT_DIR/worktrees"
    REPO_TDE="$WORKTREES_DIR/master/tde"
    REPO_EXTRA_DEPENDENCIES="$WORKTREES_DIR/master/$CFG_EXTRA_DEPS_DIR"
  else
    REPO_TDE="$TDE_DIR/$CFG_GIT_DIR/tde"
    REPO_EXTRA_DEPENDENCIES="$TDE_DIR/$CFG_GIT_DIR/$CFG_EXTRA_DEPS_DIR"
  fi
  REPO_TDE_MAIN="$REPO_TDE/main"
  REPO_TDE_PACKAGING="$REPO_TDE/packaging/$DISTRO/$DISTRO_NAME"

  BUILD_DIR="$TDE_DIR/$CFG_BUILD_DIR"
  TDE_BUILD_DIR="$BUILD_DIR/build"
  TDE_DEBS_DIR="$BUILD_DIR/debs"

  HOOK_DIR="$TDE_DIR/$CFG_GIT_DIR/$CFG_HOOKS_DIR"

  SCRIPT_LOG_DIR="$TDE_DIR/$CFG_SCRIPT_LOG_DIR"
  LOG_BUILD_RESULT_FILENAME="$SCRIPT_LOG_DIR/build_result.log"  # Common build logfile
  LOG_UPDATE_REPO_FILENAME="$SCRIPT_LOG_DIR/update_repo.log"    # Update repository logfile

  set +a
}

#----------------------------
function init_common()
{
	local CURR_DIR=`pwd`

  # Check script folder
  export SCRIPT_DIR=$(dirname $(readlink -f "$0"))

  # Prevent the script to be run from TDE packaging repo
  REPO_URL=$(git config --get remote.origin.url 2>/dev/null)
  if [ ! -z "$REPO_URL" ] && [ -z "${REPO_URL##*tde/packaging}" ]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo "This script cannot be run from the TDE packaging repository."
    echo "Please follow the instructions provided, then rerun this script."
    exit 1
  fi

  # Read config settings
  CFG_FILE=$SCRIPT_DIR/_config.sh
  if [ -f "$CFG_FILE" ]; then
    . "$CFG_FILE"
    _set_path_variables
  else
    echo -e "${CLightRed}  --- NOTE ---${CNone}"
    echo -e "Creating TDE build configuration file from template as ${CLightPurple}$CFG_FILE${CNone}."
    echo    "Please check and modify as required, then rerun this script."
    cp "$SCRIPT_DIR/internals/_config_template.sh" "$CFG_FILE"
    exit 2
  fi

  # Make sure we have selected a supported distribution
  DISTROS_FILE="$SCRIPT_DIR/internals/distro_list.txt"
  if [ ! -f "$DISTROS_FILE" ]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo    "Could not find the list of supported distributions."
    echo -e "Please check the file ${CLightPurple}$DISTROS_FILE${CNone} exists, then rerun this script."
    exit 3
  fi
  # -- Need to use a "here string" otherwise if the DISTRO_FOUND value is modified
  # -- inside the while loop, this would not remember after the loop.
  DISTRO_FOUND="n"
  OLD_IFS=$IFS && IFS=$' \t'
  while read l_distro l_version l_name l_rel_suffix l_packaging_path; do
    if [ "$l_distro" = "$DISTRO" -a "$l_name" = "$DISTRO_NAME" ]; then
      DISTRO_FOUND="y"
      l_rel_suffix=`echo "$l_rel_suffix" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"`
      l_packaging_path=`echo "$l_packaging_path" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"`
      export DISTRO_VERSION="$l_version"
      export REL_SUFFIX="$l_rel_suffix"
      if [[ ! -z "$l_packaging_path" ]]; then
        REPO_TDE_PACKAGING="$TDE_DIR/$CFG_GIT_DIR/tde/packaging/$l_packaging_path"
      fi
      break
    fi
  done <<< $(sed -n "s|\(^[\s]*[^#\s]\+.*$\)|\1|p" < $DISTROS_FILE)
  IFS=$OLD_IFS
  if [ "$DISTRO_FOUND" != "y" ]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo -e "The specified distribution (${CYellow}$DISTRO $DISTRO_NAME${CNone}) is not supported."
    echo -e "Something is wrong with your configuration (${CLightPurple}$CFG_FILE${CNone})"
    echo -e "or with the list of supported distributions (${CLightPurple}$DISTROS_FILE${CNone})."
    echo -e "Please check the ${CLightCyan}DISTRO${CNone} and ${CLightCyan}DISTRO_NAME${CNone} variables, then rerun this script."
    exit 4
  fi

  # TDE root folder must exist
  if [ ! -d "$TDE_DIR" ]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo    "A valid TDE root folder could not be located. Something is wrong with your configuration"
    echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}"
    echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} variable as required, then rerun this script."
    exit 5
  fi

  # Search for TDE repo
  found=0
  tde_config_file=""
  if [ "${USE_GIT_WORKTREES}" = "y" ]; then
    tde_config_file="$REPOS_DIR/tde.git/config"
  else
    tde_config_file="${REPO_TDE}/.git/config"
  fi
  [ -f "${tde_config_file}" ] && [ "`grep \"\\[core\\]\" ${tde_config_file}`" = "[core]" ] && found=1
  if [[ found -ne 1 ]]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo    "The main TDE repo could not be located. Something is wrong with your configuration"
    echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}"
    echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} and ${CLightCyan}USE_GIT_WORKTREES${CNone} variables as required."
    echo -e "Then rerun this script."
    exit 6
  fi

  # Check branch configuration
  # - branch existance
  UPDATE_BRANCHES="${OVERRIDE_UPDATE_BRANCHES:-$UPDATE_BRANCHES}"
  if [ "${USE_GIT_WORKTREES}" = "y" ]; then
    cd "$REPOS_DIR/tde.git"
  else
    cd "$REPO_TDE"
  fi
  BRANCHES=()
  local REMOTE_BRANCHES=(`git branch --remote | grep -v "HEAD" | sed "s|origin/||g"`)
  for br in $UPDATE_BRANCHES; do
    branch=`echo "$br" | sed -e "s|^[[:space:]]*||" -e "s|[[:space:]]*$||"`
    found=0
    for rem_br in "${REMOTE_BRANCHES[@]}"; do
      if [[ "$rem_br" == "$branch" ]]; then
        found=1
        break
      fi
    done
    if [[ found -eq 1 ]]; then
      BRANCHES+=($branch)
    else
      echo -e "${CLightRed}  --- ERROR ---${CNone}"
      echo -e "Invalid branch specified (${CYellow}$branch${CNone}). Something is wrong with your configuration"
      echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}"
      echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script."
      exit 8
    fi
  done
  if [ ${#BRANCHES[@]} -eq 0 ]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo -e "No valid branch was specified. Something is wrong with your configuration"
    echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}"
    echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script."
    exit 9
  fi
  export BRANCHES
  # - default branch
  DEFAULT_REPO_BRANCH=${OVERRIDE_DEFAULT_REPO_BRANCH:-"$DEFAULT_REPO_BRANCH"}
  found=0
  for branch in "${BRANCHES[@]}"; do
    if [[ "$DEFAULT_REPO_BRANCH" == "$branch" ]]; then
      found=1
      break
    fi
  done
  if [[ found -ne 1 ]]; then
    echo -e "${CLightRed}  --- ERROR ---${CNone}"
    echo -e "Invalid default repo branch specified (${CYellow}$DEFAULT_REPO_BRANCH${CNone}). Something is wrong with your configuration"
    echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}"
    echo -e "Please check and modify the ${CLightCyan}DEFAULT_REPO_BRANCH${CNone} variable as required, then rerun this script."
    exit 10
  fi

  cd "${CURR_DIR}"
}


#----------------------------
# Save execution start time
# Parameters:
#  $1 - timer number
function exec_time_start()
{
  _ET_start_var="_ET_start_$1"
  eval "$_ET_start_var=`date +%s.%N`"
}


#----------------------------
# Save execution stop time and set $2 to the execution time
# in the format: dd/hh:mm:ss.mmm
# Parameters:
#  $1 - timer number
#  $2 - result variable name
function exec_time_stop()
{
  _ET_start_var="_ET_start_$1"
  _ET_stop_var="_ET_stop_$1"
  eval "$_ET_stop_var=`date +%s.%N`"
  _ET_diff=`echo "${!_ET_stop_var} - ${!_ET_start_var}" | bc`
  _ET_days=`echo "$_ET_diff/86400" | bc`
  _ET_diff_day=`echo "$_ET_diff-86400*$_ET_days" | bc`
  _ET_hours=`echo "$_ET_diff_day/3600" | bc`
  _ET_diff_hour=`echo "$_ET_diff_day-3600*$_ET_hours" | bc`
  _ET_mins=`echo "$_ET_diff_hour/60" | bc`
  _ET_secs=`echo "$_ET_diff_hour-60*$_ET_mins" | bc`
  local _resultvar=$2
  eval "$_resultvar=`printf \"%02d/%02d:%02d:%06.3f\" $_ET_days $_ET_hours $_ET_mins $_ET_secs`"
}
