#!/bin/bash

## A script to convert a certificate profile and upload it to Virtuoso

# Define a usage function to print the script usage
function usage {
  echo "Usage: $0 -f [VALUE] -p [VALUE] -n [VALUE] -t [VALUE] -o [VALUE] -a [VALUE] -w [VALUE] (-d [VALUE])"
}

# Function to print the help message
function help {
  usage
  echo ""
  echo "This script takes in the following parameters:"
  echo "  -f [VALUE]      Path to the certificate profile file"
  echo "  -p [VALUE]      The certificate profile's password"
  echo "  -w [VALUE]      The directory to store the generated NSSDB within"
  echo "  -n [VALUE]      Name to use for the uploaded certificate"
  echo "  -d [VALUE]      (Optional) Description to use for the uploaded certificate"
  echo "  -t [VALUE]      Virtuoso access token"
  echo "  -o [VALUE]      Virtuoso organization ID (e.g. https://app.virtuoso.qa/#/organization/{ORG-ID}/projects)"
  echo "  -a [VALUE]      Base URL for Virtuoso API (e.g. https://api.virtuoso.qa/api/)"
  echo ""
  echo "Optional parameter:"
  echo "  --help                 Print this help message"
}

# Function to check if a variable is defined and not equal to "unset"
function is_defined {
    if [[ ! -z "${1+x}" && "${1}" != "unset" ]]; then
        return 0 # Return success status code (0) if the variable is defined and not equal to "unset"
    else
        return 1 # Return failure status code (non-zero) if the variable is undefined or equal to "unset"
    fi
}

# Parse command-line arguments
while getopts ":f:p:w:n:d:t:o:a:h" opt; do
  case ${opt} in
    f ) certPath="${OPTARG}";;
    p ) certPass="${OPTARG}";;
    w ) nssdbDir="${OPTARG}";;
    n ) certName="${OPTARG}";;
    d ) certDescription="${OPTARG}";;
    t ) virtuosoToken="${OPTARG}";;
    o ) virtuosoOrg="${OPTARG}";;
    a ) virtuosoApi="${OPTARG}";;
    h )
      help
      exit 0
      ;;
    \? )
      echo "Invalid option: -$OPTARG" 1>&2
      help
      exit 1
      ;;
    : )
      echo "Option -$OPTARG requires an argument" 1>&2
      help
      exit 1
      ;;
  esac
done

# Check if all 5 required parameters are defined and not equal to "unset"
if ! is_defined "${certPath}" || ! is_defined "${certPass}" || ! is_defined "${nssdbDir}" || ! is_defined "${certName}" || ! is_defined "${virtuosoToken}" || ! is_defined "${virtuosoOrg}" || ! is_defined "${virtuosoApi}"; then
  echo "All required parameters must be defined"
  help
  exit 1
fi

# Clear description if "unset"
if ! is_defined "${certDescription}"; then
  unset certDescription
fi

# Exit if NSSDB was not generated
if [ ! -f ${certPath} ]; then
    echo "No certificate profile file"
    exit 1
fi

# Generate NSSDB via pk12util
echo "Generating NSSDB from ${certPath} (to ${nssdbDir})"
pk12util -d sql:${nssdbDir} -i $certPath -W "${certPass}" -K ""

# Exit if NSSDB was not generated
if [ -z "$(ls -A ${nssdbDir})" ]; then
    echo "Failed to generate NSSDB from certificate profile."
    exit 1
fi

echo "Creating certificate entry on Virtuoso..."
# Make certificate creation payload
certCreatePayload="{ \"name\": \"${certName}\" "
if [ -n "$certDescription" ]; then
  certCreatePayload+=", \"description\": \"${certDescription}\""
fi
certCreatePayload+=" }"
# Make the request
responseCert=$(curl -X POST \
    -H "Authorization: Bearer ${virtuosoToken}"  \
    -H "Content-Type: application/json" \
    -d "${certCreatePayload}" \
    ${virtuosoApi}/organizations/${virtuosoOrg}/certificates)
# Check certificate entry was created
responseCertCreateSuccess=$(echo ${responseCert} | jq --raw-output '.success')
if [ "$responseCertCreateSuccess" != "true" ]; then
  echo "Failed to create certificate entry on Virtuoso!"
  echo "Please check that:"
  echo "1. Your access token is correct;"
  echo "2. Your certificate's name is unique."
  exit 1
fi
# Extract URLs from JSON response
responseCertId=$(echo ${responseCert} | jq --raw-output '.item.id')
uploadUrlKey4=$(echo ${responseCert} | jq --raw-output '.item.s3PreSignedUrls."key4.db"')
uploadUrlCert9=$(echo ${responseCert} | jq --raw-output '.item.s3PreSignedUrls."cert9.db"')
uploadUrlPKCS11=$(echo ${responseCert} | jq --raw-output '.item.s3PreSignedUrls."pkcs11.txt"')

echo "Uploading certificate files..."
$(curl -X PUT -T ${nssdbDir}/key4.db ${uploadUrlKey4})
$(curl -X PUT -T ${nssdbDir}/cert9.db ${uploadUrlCert9})
$(curl -X PUT -T ${nssdbDir}/pkcs11.txt ${uploadUrlPKCS11})

echo "Verifying that certificate files were successfully uploaded..."
echo $responseCertId
responseVerify=$(curl -X PUT \
    -H "Authorization: Bearer ${virtuosoToken}"  \
    -H "Content-Type: application/json" \
    ${virtuosoApi}/organizations/${virtuosoOrg}/certificates/${responseCertId}/verify)
responseVerifySuccess=$(echo ${responseVerify} | jq --raw-output '.success')

if [ "$responseVerifySuccess" != "true" ]; then
  echo "Failed to upload certificate files!"
  exit 1
fi

echo ""
echo "Successfully uploaded certificate!"
echo "Certificate ID: ${responseCertId}"