#!/bin/bash -e

set -o pipefail
shopt -s nullglob


# ------------------------------ Helper Functions ------------------------------

## Remove file if it exists at provided path
#
# Usage:
#   $ maybe_remove_file /path/to/file

maybe_remove_file() {
  local -r path="$1"

  rm -f "${path}"
  mkdir -p "$(dirname "${path}")"  
}

# ------------------------------- TLS Functions --------------------------------

## Generates a JKS file at specified path for provided CA certificate
#
# Usage:
#   $ gen_jks_for_cert /path/to/ca-cert /path/to/jks

gen_jks_for_cert() {
  local -r ca_cert_path="$1"
  local -r jks_path="$2"
  local -r certs=$(grep -c 'END CERTIFICATE' "${ca_cert_path}")

  for ((i=0; i<certs; i++)); do
    awk "N==${i} { print }; /END CERTIFICATE/ { N++ }" "${ca_cert_path}" |
    keytool\
      -noprompt\
      -importcert\
      -trustcacerts\
      -alias "manager-store-ca-${i}"\
      -keystore "${jks_path}"\
      -storepass imply-onprem
  done
}

## Generates a JKS file at specified path for provided client certificate-key pair
#
# Usage:
#   $ gen_jks_for_cert_key_pair /path/to/client-cert /path/to/client-key /path/to/jks

gen_jks_for_cert_key_pair() {
  local -r client_cert_path="$1"
  local -r client_key_path="$2"
  local -r jks_path="$3"
  local -r pkcs12_path=$(mktemp -d)/imply-mysql-client-keystore.p12

  openssl\
    pkcs12\
    -export\
    -in "${client_cert_path}"\
    -inkey "${client_key_path}"\
    -passout pass:imply-onprem\
    -out ${pkcs12_path}

  keytool\
    -importkeystore\
    -srckeystore ${pkcs12_path}\
    -srcstoretype pkcs12\
    -srcstorepass imply-onprem\
    -destkeystore "${jks_path}"\
    -deststoretype JKS\
    -deststorepass imply-onprem

  rm ${pkcs12_path}
}

## Generates a PK8 file at specified path for provided client key
#
# Usage:
#   $ gen_pk8_for_key /path/to/client-key /path/to/pk8

gen_pk8_for_key() {
  local -r client_key_path="$1"
  local -r pk8_path="$2"

  openssl\
    pkcs8\
    -topk8\
    -nocrypt\
    -inform PEM\
    -in "${client_key_path}"\
    -outform DER\
    -out "${pk8_path}"

  chmod o+r "${pk8_path}"
}

if [[ -f "${IMPLY_MANAGER_STORE_CA_CERT_PATH}" ]]; then

  if [[ "${IMPLY_MANAGER_STORE_TYPE}" == "mysql" ]]; then

    # ------------------- Generate JKS for MySQL JDBC Connector --------------------

    echo "Converting manager store CA certificates [${IMPLY_MANAGER_STORE_CA_CERT_PATH}]"\
        "to JKS [${IMPLY_MANAGER_STORE_CA_JKS_PATH}]"

    # ------------------------- Maybe Clear Existing JKS -------------------------

    maybe_remove_file "${IMPLY_MANAGER_STORE_CA_JKS_PATH}"

    # ----------------------- Generate JKS Per Certificate -----------------------

    gen_jks_for_cert "${IMPLY_MANAGER_STORE_CA_CERT_PATH}" "${IMPLY_MANAGER_STORE_CA_JKS_PATH}"
  fi

  
  if [ -f "${IMPLY_MANAGER_STORE_CLIENT_CERT_PATH}" ] && [ -f "${IMPLY_MANAGER_STORE_CLIENT_KEY_PATH}" ]; then

    if [[ "${IMPLY_MANAGER_STORE_TYPE}" == "mysql" ]]; then

      # --------------------- Maybe Create Client Cert Key JKS ---------------------
      
      echo -e "\nConverting manager store client certificate [$IMPLY_MANAGER_STORE_CLIENT_CERT_PATH]"\
      "and key [${IMPLY_MANAGER_STORE_CLIENT_KEY_PATH}] to JKS [${IMPLY_MANAGER_STORE_CLIENT_JKS_PATH}]"

      # ------------------------- Maybe Clear Existing JKS -------------------------
    
      maybe_remove_file "${IMPLY_MANAGER_STORE_CLIENT_JKS_PATH}"

      # --------------------- Generate JKS for Client Key Pair ---------------------
    
      gen_jks_for_cert_key_pair "${IMPLY_MANAGER_STORE_CLIENT_CERT_PATH}" "${IMPLY_MANAGER_STORE_CLIENT_KEY_PATH}" "${IMPLY_MANAGER_STORE_CLIENT_JKS_PATH}"

    else
      # ----------------- Maybe PK8 for PostgreSQL JDBC Connector ------------------

      echo -e "\nConverting manager store client key [${IMPLY_MANAGER_STORE_CLIENT_KEY_PATH}]"\
      "from PEM to PK8 at [${IMPLY_MANAGER_STORE_CLIENT_PK8_PATH}]"

      # ------------------------- Maybe Clear Existing PK8 -------------------------

      maybe_remove_file "${IMPLY_MANAGER_STORE_CLIENT_PK8_PATH}"

      # ----------------------- Generate PK8 for Client Key ------------------------

      gen_pk8_for_key "${IMPLY_MANAGER_STORE_CLIENT_KEY_PATH}" "${IMPLY_MANAGER_STORE_CLIENT_PK8_PATH}"
    fi
  fi
fi