#!/usr/bin/env bash

set -Eeuo pipefail

nevisadmin4_namespace=''
job_name='nevisadmin4-dbschema'
image_prefix=''
image_version=''
container_registry=''
isRollback=false

parseParams() {
    while :; do
        case "${1-}" in
        --rollback) isRollback=true ;;
        -n | --nevisadmin4-namespace)
            nevisadmin4_namespace="${2-}"
            shift
            ;;
        -c | --container-registry)
            container_registry="${2-}"
            shift
            ;;
        -?*) ./lib/die.sh "Unknown option: $1" ;;
        *) break ;;
        esac
        shift
    done

    [[ -z "${nevisadmin4_namespace-}" ]] && ./lib/die.sh "Missing required parameter: nevisadmin4-namespace"

    if [[ -z $container_registry ]] ; then
        ./lib/die.sh "The container-registry must be set"
    fi

    image_prefix=$(lib/yq_linux_amd64 'e' '.image-prefix' 'lib/config.yaml')
    image_version=$(lib/yq_linux_amd64 'e' '.versions.nevisadmin4-dbschema' 'lib/config.yaml')
    job_name=$(lib/yq_linux_amd64 'e' '.db-schema-job' 'lib/config.yaml')
}

runChecks() {
    ./lib/msg.sh "Checking permissions..."
    ./lib/check-permissions.sh "get jobs" "$nevisadmin4_namespace"
    ./lib/check-permissions.sh "delete jobs" "$nevisadmin4_namespace"
    ./lib/check-permissions.sh "create jobs" "$nevisadmin4_namespace"
}

# Creates a new nevisadmin4-dbschema job from the current one by updating the image version
createNewDatabaseJob() {
    getDatabaseJobCommand="kubectl get job $job_name -n $nevisadmin4_namespace -o yaml"
    ./lib/msg.sh "Downloading database job: $getDatabaseJobCommand"
    dbJob=$(eval "$getDatabaseJobCommand")
    echo "$dbJob" > lib/tmp/dbJob.yaml

    lib/yq_linux_amd64 'e' 'del(.spec.selector)' 'lib/tmp/dbJob.yaml' '--inplace'                 # delete auto generated fields
    lib/yq_linux_amd64 'e' 'del(.spec.template.metadata.labels)' 'lib/tmp/dbJob.yaml' '--inplace'

    lib/yq_linux_amd64 'e' 'del(.metadata.annotations)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.metadata.creationTimestamp)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.metadata.labels)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.metadata.resourceVersion)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.metadata.selfLink)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.metadata.uid)' 'lib/tmp/dbJob.yaml' '--inplace'

    lib/yq_linux_amd64 'e' 'del(.spec.selector)' 'lib/tmp/dbJob.yaml' '--inplace'
    lib/yq_linux_amd64 'e' 'del(.spec.template.metadata)' 'lib/tmp/dbJob.yaml' '--inplace'

    lib/yq_linux_amd64 'e' 'del(.status)' 'lib/tmp/dbJob.yaml' '--inplace'

    ./lib/msg.sh "Modifying the database job with the new version"
    imageIndex="$(lib/yq_linux_amd64 'e' '.spec.template.spec.containers.[] | select(.name == "nevisadmin4-dbschema") | path | .[-1]' 'lib/tmp/dbJob.yaml')"
    lib/yq_linux_amd64 'e' ".spec.template.spec.containers[$imageIndex].image = \"$container_registry/$image_prefix/nevisadmin4-dbschema:$image_version\"" 'lib/tmp/dbJob.yaml' '--inplace'
}

# Deletes the previous nevisadmin4-dbschema job, to make way for the new one
removePreviousJob() {
    deleteDatabaseJobCommand="kubectl delete job $job_name -n $nevisadmin4_namespace"
    ./lib/msg.sh "Removing previous database job: $deleteDatabaseJobCommand"
    eval "$deleteDatabaseJobCommand"
}

# Applies lib/tmp/dbJob.yaml (the new nevisadmin4-dbschema job) to the cluster
applyNewJob() {
    createDatabaseJobCommand="kubectl apply -f lib/tmp/dbJob.yaml -n $nevisadmin4_namespace"
    ./lib/msg.sh "Applying the new database job to the cluster: $createDatabaseJobCommand"
    eval "$createDatabaseJobCommand"

    waitForDataBaseJobCommand="kubectl wait --for=condition=complete --timeout=10m job/$job_name -n $nevisadmin4_namespace"
    ./lib/msg.sh "Waiting for the database job to finish: $waitForDataBaseJobCommand"
    eval "$waitForDataBaseJobCommand"
}

main() {
    parseParams "$@"

    ./lib/msg.sh ""
    ./lib/msg.sh "-------- Nevisadmin database upgrade ---------"

    if [[ $isRollback = true ]] ; then
        ./lib/msg.sh "The database schema cannot be rolled back."
        return
    fi

    ./lib/msg.sh "This part of the script will upgrade the nevisadmin4 database. It first removes the previous nevisadmin4-dbschema"
    ./lib/msg.sh "job, then applies the new one, at lib/tmp/dbJob.yaml. Note that this step can not be rolled back."

    read -p "Upgrade the nevisAdmin4 database? [y/n]" -n 1 -r
    printf '\n'
    if [[ ! $REPLY =~ ^[Yy]$ ]] ; then
       return
    fi

    runChecks
    createNewDatabaseJob
    removePreviousJob
    applyNewJob
    ./lib/msg.sh "Nevisadmin database upgrade completed."
}

main "$@"
