#!/usr/bin/env bash
# ==========================================================================
#     _   _ _ ____            ____          _____
#    | | | (_)  _ \ ___ _ __ / ___|___  _ _|_   _| __ __ _  ___ ___ _ __
#    | |_| | | |_) / _ \ '__| |   / _ \| '_ \| || '__/ _` |/ __/ _ \ '__|
#    |  _  | |  __/  __/ |  | |__| (_) | | | | || | | (_| | (_|  __/ |
#    |_| |_|_|_|   \___|_|   \____\___/|_| |_|_||_|  \__,_|\___\___|_|
#
#       ---  High-Performance Connectivity Tracer (HiPerConTracer)  ---
#                 https://www.nntb.no/~dreibh/hipercontracer/
# ==========================================================================
#
# High-Performance Connectivity Tracer (HiPerConTracer)
# Copyright (C) 2015-2026 by Thomas Dreibholz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Contact: dreibh@simula.no

# Bash options:
set -euo pipefail


# ###### Usage ##############################################################
usage () {
   local exitCode="$1"
   echo >&2 "Usage: $0 database_configuration_file ... [--join] [-h|--help] [-v|--version]"
   exit "${exitCode}"
}


# ###### Version ############################################################
version () {
   echo "Make-DBeaver-Configuration @BUILD_MAJOR@.@BUILD_MINOR@.@BUILD_PATCH@"
   exit 0
}



# ###### Main program #######################################################

# ====== Handle arguments ===================================================
if (( BASH_VERSINFO[0] < 4 )) || (( (BASH_VERSINFO[0] == 4) && (BASH_VERSINFO[1] < 4) )) ; then
   echo "ERROR: Bash 4.4 or higher is required, but Bash ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]} is installed!"
   exit 1
fi
GETOPT="$(PATH="/usr/local/bin:${PATH}" command -v getopt)"
if "${GETOPT}" -T >/dev/null 2>&1 || [[ $? -ne 4 ]]; then
   echo >&2 "ERROR: Enhanced/GNU getopt is required!"
   exit 1
fi
options="$(${GETOPT} -o jhv --long join,help,version -a -- "$@")"
# shellcheck disable=SC2181
if [[ $? -ne 0 ]]; then
   usage 1
fi

JOIN=0
eval set -- "${options}"
while [ $# -gt 0 ] ; do
   case "$1" in
      -j | --join)
         JOIN=1
         ;;
      -h | --help)
         usage 0
         ;;
      -v | --version)
         version
         ;;
      --)
         shift
         break
         ;;
      *)
         # This should not happen: wrong getopt parameters, or missing case?
         echo >&2 "INTERNAL ERROR: Unhandled option $1!"
         exit 1
         ;;
  esac
  shift
done
if [ $# -lt 1 ] ; then
   usage 1
fi
DIRNAME="$(dirname "$0")"


# ====== Process configuration files ========================================
echo -e "\x1b[34m$(date +"%F %H:%M:%S"): Generating DBeaver configuration ...\x1b[0m"
tempDirectory="$(mktemp -d -t "make-dbeaver-configuration-XXXXXX")"
trap 'rm -rf "${tempDirectory}"' EXIT

dbeaverConfig=""
dbeaverCredentials=""
while [ $# -gt 0 ] ; do
   echo -e "\x1b[37mProcessing $(basename "$1") ...\x1b[0m"
   "${DIRNAME}/dbshell" "$1" --dry-run --quiet --write-dbeaver-config "${tempDirectory}/$(basename "${1//.conf/}")"
   shift
done


# ====== Read existing configuration ========================================
if [ ${JOIN} -eq 1 ] ; then
   echo -e "\x1b[37mLooking for existing DBeaver configuration ...\x1b[0m"
   for dbeaverDirectory in \
      "${HOME}/snap/dbeaver-ce/current/.local/share/DBeaverData/workspace6/General/.dbeaver" \
      "${HOME}/.local/share/DBeaverData/workspace6/General/.dbeaver" ; do
      if [ -e "${dbeaverDirectory}" ] ; then
         if [ -e "${dbeaverDirectory}/data-sources.json" ] ; then
            dbeaverConfig="${dbeaverDirectory}/data-sources.json"
            echo -e "\x1b[37mJoining data sources in ${dbeaverConfig}\x1b[0m"
         fi
         if [ -e "${dbeaverDirectory}/credentials-config.json" ] ; then
            dbeaverCredentials="${tempDirectory}/credentials-config.json"
            echo -e "\x1b[37mJoining credentials in ${dbeaverDirectory}/credentials-config.json\x1b[0m"
            "${DIRNAME}/decrypt-dbeaver-configuration" \
               "${dbeaverDirectory}/credentials-config.json" \
               "${dbeaverCredentials}"
         fi
         break
      fi
   done
   if [ ! -e "${dbeaverDirectory}" ] ; then
      echo >&2 "ERROR: Unable to find DBeaver configuration directory!"
      exit 1
   fi
fi


# ====== Join new DBeaver configuration files ===============================
echo -e "\x1b[37mJoining configurations ...\x1b[0m"
# shellcheck disable=SC2086
jq --sort-keys --slurp 'reduce .[] as $item ({}; . * $item)' ${dbeaverConfig}      "${tempDirectory}"/*-data-source.json >"${tempDirectory}/data-sources.json"
# shellcheck disable=SC2086
jq --sort-keys --slurp 'reduce .[] as $item ({}; . * $item)' ${dbeaverCredentials} "${tempDirectory}"/*-credentials-config.json >"${tempDirectory}/credentials-config.json.plaintext"

# Encrypt the new credentials files:
"${DIRNAME}/encrypt-dbeaver-configuration" \
   "${tempDirectory}/credentials-config.json.plaintext" \
   "${tempDirectory}/credentials-config.json"


# ====== Join with existing configuration ===================================
if [ ${JOIN} -eq 1 ] ; then
   if [ "${dbeaverConfig}" != "" ] ; then
      if ! diff "${tempDirectory}/data-sources.json" "${dbeaverDirectory}/data-sources.json" >/dev/null ; then
         dbeaverConfigBackup="${dbeaverConfig}.backup-$(date +"%F-%H:%M:%S")"
         echo -e "\x1b[37mMaking data sources backup in ${dbeaverConfigBackup} ...\x1b[0m"
         cp "${dbeaverConfig}" "${dbeaverConfigBackup}"
      fi
   fi
   echo -e "\x1b[37mUpdating data sources ${dbeaverDirectory}/data-sources.json ...\x1b[0m"
   mv "${tempDirectory}/data-sources.json" "${dbeaverDirectory}/data-sources.json"

   if [ "${dbeaverCredentials}" != "" ] ; then
      if ! diff "${dbeaverCredentials}" "${tempDirectory}/credentials-config.json.plaintext" >/dev/null ; then
         dbeaverCredentialsBackup="${dbeaverDirectory}/credentials-config.json-$(date +"%F-%H:%M:%S")"
         echo -e "\x1b[37mKeeping backup in ${dbeaverCredentialsBackup} ...\x1b[0m"
         cp "${dbeaverCredentials}" "${dbeaverCredentialsBackup}"
      fi
   fi
   echo -e "\x1b[37mUpdating credentials ${dbeaverDirectory}/credentials-config.json ...\x1b[0m"
   mv "${tempDirectory}/credentials-config.json" "${dbeaverDirectory}/credentials-config.json"

else

   # Just generated the configuration files -> no joining was performed!
   mv "${tempDirectory}/data-sources.json" "${tempDirectory}/credentials-config.json" .
   echo "Generated configuration files:"
   ls -l credentials-config.json data-sources.json

fi


# ====== Clean up ===========================================================
echo -e "\x1b[37mDone!\x1b[0m"
rm -rf "${tempDirectory}"
