#!/usr/bin/env bash
set -e

this=$(basename "${BASH_SOURCE[0]}")
name=${RELEASE:-${1:-participant-portal}}
ns=${NAMESPACE:-${2:-rtgsglobal}}
VALUES_FILE=${LOCAL_VALUES:-values-local.yaml}

# set the Docker namespace preference
function set_ns {
    local ns=$1
    local context="docker-desktop"
    local current_context=$(kubectl config current-context)

    if [[ "$current_context" != "$context" ]]; then
        echo "Switching context to \"$context\""
        kubectl config use-context $context
    fi

    local ns_exists=$(kubectl get namespace $ns --ignore-not-found)

    if [[ -z "$ns_exists" ]]; then
        echo "Creating namespace \"$ns\"..."
        kubectl create namespace $ns
    fi

    local current_ns=$(kubectl config view | grep namespace: | cut -d":" -f2 | cut -d" " -f2)

    if [[ "$current_ns" != "$ns" ]]; then
        echo "Setting namespace preference to \"$ns\""
        kubectl config set-context --current --namespace=$ns
    fi
}

# install self signed certificate for local hosting
function install_tls_cert {
    local host=$1
    local secret_name=$2

    if kubectl get secret "$secret_name" -n "$ns" &>/dev/null; then
        echo "Skipping - TLS secret '$secret_name' already exists in namespace '$ns'."
    else
        echo "Creating self-signed certificate for $host..."
        local temp_dir=$(mktemp -d)
        trap "rm -rf $temp_dir" EXIT
        openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
            -keyout "$temp_dir/tls.key" \
            -out "$temp_dir/tls.crt" \
            -subj "/CN=$host" \
            -addext "subjectAltName=DNS:$host" \
            2>/dev/null
        kubectl create secret tls "$secret_name" \
            --cert="$temp_dir/tls.crt" \
            --key="$temp_dir/tls.key" \
            -n "$ns"

        echo "TLS secret '$secret_name' created successfully"
    fi
}

# enable localhost routing
function install_nginx {
    if helm status ingress-nginx --namespace default >/dev/null 2>&1; then
        echo "Skipping - nginx ingress is already installed."
    else
        echo "Adding repo kubernetes.github.io/ingress-nginx..."
        helm repo add nginx https://kubernetes.github.io/ingress-nginx
        echo "Installing ingress-nginx..."
        helm upgrade --install --dependency-update --reuse-values --namespace default ingress-nginx nginx/ingress-nginx
        echo "Waiting for ingress-nginx to be ready..."
        sleep 3s
        echo
    fi
}

# install metrics-server
function install_metrics_server {
    if kubectl get deployment metrics-server -n kube-system &>/dev/null; then
        echo "Skipping - metrics server is already installed."
    else
        echo "Installing metrics-Server..."
        kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
        kubectl patch deployment metrics-server -n kube-system \
            --type=json \
            -p='[{
                "op": "add", "path": "/spec/template/spec/containers/0/args/-",
                "value": "--kubelet-insecure-tls"
            }, {
                "op": "add", "path": "/spec/template/spec/containers/0/args/-",
                "value": "--kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP"
            }]'

        echo "Waiting for metrics-server to be ready..."
        kubectl rollout status deployment/metrics-server -n kube-system
        echo "metrics-server installed"
        echo
    fi
}

# install cloud native postgres
function install_cnpg {
    if helm status cnpg --namespace cnpg-system >/dev/null 2>&1; then
        echo "Skipping - cloud native postgres is already installed."
    else
        echo "Adding repo cloudnative-pg.github.io/charts..."
        helm repo add cnpg https://cloudnative-pg.github.io/charts
        echo "Installing cnpg..."
        helm upgrade --wait --install --dependency-update --reuse-values \
            --namespace cnpg-system \
            --create-namespace \
            cnpg \
            cnpg/cloudnative-pg
        echo "Waiting for cnpg to be ready..."
        sleep 3s
        echo
    fi
}

# create Helm deployment
function helm_install {
    local name=$1
    local ns=$2
    echo "Deploying ./Chart.yaml as $name into $ns..."
    helm upgrade --wait --install --dependency-update --debug \
        --namespace "$ns" \
        --values "./values.yaml" \
        --values "./${VALUES_FILE}" \
        "$name" \
        "."
}

pushd "$(dirname "${BASH_SOURCE[0]}")/.."

if grep -qP "<[^>]+>" ./${VALUES_FILE}; then
    echo "Error: ${VALUES_FILE} contains unreplaced placeholders:"
    grep -P "<[^>]+>" ./${VALUES_FILE}
    exit 1
fi

set_ns $ns
install_nginx
install_metrics_server
install_cnpg
install_tls_cert portal.local portal-tls
install_tls_cert notifications.local notifications-tls
helm_install $name $ns
popd
