#!/bin/bash

set -e
# Set default version
VERSION="8.2511.4"
IMAGE_VERSION="8.2511.0"
# Set default helm settings as empty
HELM_SETTINGS=""
MARIADB_CHART_VERSION="4.4.3"

# Function to generate a random password
generate_password() {
    openssl rand -base64 48 | tr -dc '[:alnum:]' | head -c 16
}

# Function to display script usage
function display_usage() {
  echo "### Usage: $0"
  echo -e "    --upgrade                                                \t upgrade an existing installation"
  echo -e "    --add-nginx-node-port                                    \t "
  echo -e "    --add-nginx-load-balancer                                \t "
  echo -e "    --namespace <namespace>                                  \t required"
  echo -e "    --domain <domain>                                        \t required"
  echo -e "    --container-registry <container_registry>                \t required"
  echo -e "    --registry-username <registry_username>                  \t required"
  echo -e "    --registry-password <registry_password>                  \t required"
  echo -e "    --cloudsmith-password <cloudsmith_password>              \t required if not using a separate helm repository"
  echo -e "    --nevisadmin-password <nevisadmin_password>              \t"
  echo -e "    --git-password <git_password>                            \t"
  echo -e "    --database-password <database_password>                  \t"
  echo -e "    --version <chart_version>                                \t"
  echo -e "    --helm-repository <helm_repository>                      \t"
  echo -e "    --helm-repository-username <helm_repository_password>    \t"
  echo -e "    --helm-repository-password <helm_repository_username>    \t"
  echo -e "    --cluster-context                                        \t switch to the given context"
  echo -e "    --skip-images                                            \t skip image pull from Cloudsmith"
  echo -e "    --no-prompt                                              \t answer y to every question"
  echo -e "    --helm-setting <setting>                                 \t add a custom helm value to the installation with --set"
  echo -e "    --image-version <image_version>                          \t"
  echo -e "    --help                                                   \t show this help"
}

check_helm() {
    # Check if Helm is installed
    if ! command -v helm &> /dev/null
    then
        # Ask the user if they want to install Helm
        read -r -p "### Helm is required for the installation process. Do you want to install Helm now? (y/n) " install_helm
        if [[ $install_helm == "y" ]]; then
            echo "### Installing Helm..."
            curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
        else
            echo "### Helm installation skipped. Please install Helm and re-run this script."
            exit 1
        fi
    else
        echo "### Helm is available, continuing the installation."
    fi
}

helm_login () {
    if [[ "$HELM_REPOSITORY" == *"oci://"* ]]; then
        echo "### Logging into helm registry $HELM_REPOSITORY"
        LOGIN_HELM_REPOSITORY=$(echo "$HELM_REPOSITORY" | sed 's/oci:\/\///')
        echo "$HELM_REPOSITORY_PASSWORD" | helm registry login "$LOGIN_HELM_REPOSITORY" --username "$HELM_REPOSITORY_USERNAME" --password-stdin
        if [[ ${HELM_REPOSITORY: -1} != "/" ]]; then
            # Add a trailing slash to the registry
            HELM_REPOSITORY="${HELM_REPOSITORY}/"
        fi
        HELM_INSTALL_PREFIX="--version $VERSION $HELM_REPOSITORY"
    else
        HELM_INSTALL_PREFIX="--username $HELM_REPOSITORY_USERNAME --password $HELM_REPOSITORY_PASSWORD --repo $HELM_REPOSITORY --version $VERSION"
    fi
}

read_inputs() {
    read_domain_input
    read_release_inputs
}

read_domain_input() {
    if [ -z "$DOMAIN" ]; then
        # Ask for the domain where nevisAdmin 4 will be accessible
        read -r -p "### Enter the domain where nevisAdmin 4 will be accessible, for example 'nevis.os3434.com'. This domain will be used for a DNS A record with the IP of the nginx loadbalancer.: " DOMAIN
    fi
}

read_release_inputs() {
    if [ -z "$RELEASE_NAMESPACE" ]; then
        # Enter the namespace where nevisAdmin4 will be installed:
        read -r -p "### Enter the namespace where nevisAdmin 4 will be installed: " RELEASE_NAMESPACE
    fi

    if [ -z "$CONTAINER_REGISTRY" ]; then
        # Ask for the container registry to push the images
        read -r -p "### Enter the container registry to push the images to, for example 'os.icr.io': " CONTAINER_REGISTRY
    fi

    if [ -z "$REGISTRY_USERNAME" ]; then
        read -r -p "### Enter the username for the registry: " REGISTRY_USERNAME
    fi

    if [ -z "$REGISTRY_PASSWORD" ]; then
        read -r -p "### Enter the password for the registry: " REGISTRY_PASSWORD
    fi

    if { [ "$get_images" == "y" ] || [ -z "$HELM_REPOSITORY_PASSWORD" ]; }  && [ -z "$CLOUDSMITH_PASSWORD" ]; then
        read -r -p "### Enter the password for the nevissecurity/rolling Cloudsmith repository, you can get the password by selecting one of the docker images in 'https://portal.nevis.net/portal/secure/releases/rolling': " CLOUDSMITH_PASSWORD
    fi

    HELM_REPOSITORY="${HELM_REPOSITORY:-https://dl.cloudsmith.io/basic/nevissecurity/rolling/helm/charts}"
    HELM_REPOSITORY_USERNAME="${HELM_REPOSITORY_USERNAME:-nevissecurity/rolling}"
    HELM_REPOSITORY_PASSWORD="${HELM_REPOSITORY_PASSWORD:-$CLOUDSMITH_PASSWORD}"
}

verify_cluster(){
    if [ -n "$CLUSTER_CONTEXT" ]; then
        echo "### Switching to Kubernetes context: $CLUSTER_CONTEXT"
        oc config use-context "$CLUSTER_CONTEXT"
    fi

    # Get the name of the current Kubernetes cluster
    current_cluster=$(oc config current-context)
    echo "### Connected to Kubernetes cluster: $current_cluster"

    # Ask the user if the current cluster is correct
    if [[ $prompt == "y" ]]; then
      read -r -p "### Is this the correct Kubernetes cluster? (y/n) " correct_cluster
    else
      correct_cluster=y
    fi
    if [[ $correct_cluster != "y" ]]; then
        echo "### Please connect to the correct Kubernetes cluster and re-run this script."
        exit 1
    fi
}

install_cert_manager(){
   if oc get crd | grep -q cert-manager.io &> /dev/null
   then
       echo "### Cert-manager CRDs found, cert-manager is already installed on the cluster. Continuing the installation."
       return
   fi
   # Ask the user whether to install cert-manager or not
   if [[ $prompt == "y" ]]; then
      read -r -p "### Cert-manager is required for the installation, do you want to install cert-manager now to the 'cert-manager' namespace? This requires cluster scoped access. (y/n) " INSTALL_CERT_MANAGER
   else
      INSTALL_CERT_MANAGER=y
   fi
   if [[ $INSTALL_CERT_MANAGER != "y" ]]; then
      echo "### Please install cert-manager based on https://cert-manager.io/docs/installation/ and re-run this script."
      exit 1
   fi
   if oc auth can-i create crd >/dev/null 2>&1 && oc auth can-i create namespace >/dev/null 2>&1; then
       echo "### User has the required permissions to install cert-manager"
   else
       echo "### No permission to apply CustomResourceDefinitions to the cluster and to create namespaces, please acquire the necessary permissions then rerun this script."
       echo "### You can also install cert-manager separately by following: https://cert-manager.io/docs/installation/ "
       exit 1
   fi
   # Install cert-manager using helm
   helm install cert-manager cert-manager --create-namespace --namespace cert-manager --repo https://charts.jetstack.io --version 1.9.2 --wait --set installCRDs=true
}

install_crd() {
    if oc get crd | grep -q operator.nevis-security.ch &> /dev/null
    then
        echo "### nevisAdmin4 CRDs are already installed on the cluster. Continuing the installation."
        return
    fi
    # Ask the user whether to install crds or not
    if [[ $prompt == "y" ]]; then
        read -r -p "### Installing nevisAdmin4-crd helm chart, proceed? This requires cluster scoped permissions (y/n) " INSTALL_CRD
    else
        INSTALL_CRD=y
    fi
    if [[ $INSTALL_CRD != "y" ]]; then
        echo "### Please install based on https://docs.nevis.net/nevisadmin4/Installation/Software-Installation/Kubernetes-Based-Installation/Installation-in-Kubernetes-Cluster#install-crd-chart and re-run this script."
        exit 1
    fi

    if oc auth can-i create crd >/dev/null 2>&1; then
        echo "### User has the required permissions to install CRDs"
    else
        echo "### No permission to apply CustomResourceDefinitions to the cluster, please acquire the necessary permissions then rerun this script."
        echo "### Or install manually based on https://docs.nevis.net/nevisadmin4/Installation/Software-Installation/Kubernetes-Based-Installation/Installation-in-Kubernetes-Cluster#install-crd-chart"
        exit 1
    fi
    helm install nevisadmin4-crd -n default $HELM_INSTALL_PREFIX"nevisadmin4-crd"
}

upgrade_crd() {
    # Ask the user whether to install crds or not
    if [[ $prompt == "y" ]]; then
        read -r -p "### Upgrading nevisAdmin4-crd helm chart, proceed? This requires cluster scoped permissions (y/n) " UPGRADE_CRD
    else
        UPGRADE_CRD=y
    fi
    if [[ $UPGRADE_CRD != "y" ]]; then
        echo "### Please upgrade based on https://docs.nevis.net/nevisadmin4/Installation/Software-Upgrade/Kubernetes-Upgrade#upgrade-for-helm-installations."
        exit 1
    fi

    if kubectl auth can-i create crd >/dev/null 2>&1; then
        echo "### User has the required permissions to update CRDs"
    else
        echo "### No permission to update CustomResourceDefinitions to the cluster, please acquire the necessary permissions then rerun this script."
        echo "### Or upgrade manually based on https://docs.nevis.net/nevisadmin4/Installation/Software-Upgrade/Kubernetes-Upgrade#upgrade-for-helm-installations."
        exit 1
    fi
    helm upgrade nevisadmin4-crd -n default $HELM_INSTALL_PREFIX"nevisadmin4-crd"
}

push_images() {
    if [[ $get_images != "y" ]]; then
        return
    fi
    REGISTRY=docker.cloudsmith.io/nevissecurity/rolling
    # Ask the user whether to install crds or not
    read -r -p "### Nevis docker images will be pulled from $REGISTRY, and pushed to $CONTAINER_REGISTRY/nevis, proceed? (y/n) " PUSH_IMAGES
    if [[ $PUSH_IMAGES != "y" ]]; then
       echo "### Rerun this script and specify the correct registry."
       exit 1
    fi
    echo "### Login to registry $REGISTRY"
    docker login $REGISTRY -p "$CLOUDSMITH_PASSWORD" -u nevissecurity/rolling
    echo "### Login to registry $CONTAINER_REGISTRY"
    docker login "$CONTAINER_REGISTRY" -p "$REGISTRY_PASSWORD" -u "$REGISTRY_USERNAME"
    echo "### Pushing docker images to registry $CONTAINER_REGISTRY"
    declare -a images=("nevisproxy:8.2511.3"
                       "nevisproxy-dbschema:8.2511.3"
                       "nevislogrend:8.2511.2"
                       "nevisfido:8.2511.3"
                       "nevisfido-dbschema:8.2511.3"
                       "nevisauth:8.2511.4"
                       "nevisauth-dbschema:8.2511.4"
                       "nevisidm:8.2511.4"
                       "nevisidm-dbschema:8.2511.4"
                       "nevismeta:8.2511.2"
                       "nevismeta-dbschema:8.2511.2"
                       "nevisadmin4:8.2511.4"
                       "nevisadmin4-dbschema:8.2511.4"
                       "nevisoperator:8.2511.3"
                       "nevisadapt:8.2511.3"
                       "nevisadapt-dbschema:8.2511.3"
                       "nevisdetect-admin:8.2511.2"
                       "nevisdetect-core:8.2511.2"
                       "nevisdetect-entrypoint:8.2511.2"
                       "nevisdetect-persistency:8.2511.2"
                       "nevisdetect-persistency-dbschema:8.2511.2"
                       "nevis-git-init:1.4.0"
                       "nevisdp:8.2511.3"
                       "nevis-ubi-tools:1.5.0"
                       "nevis-base-flyway:8.2511.1")
    for i in "${images[@]}"; do
        docker pull $REGISTRY/"$i"
        docker tag $REGISTRY/"$i" "$CONTAINER_REGISTRY"/nevis/"$i"
        docker push "$CONTAINER_REGISTRY"/nevis/"$i"
    done
}

install_mariadb() {
    namespace=$1
    tz_init_script=$'#!/bin/bash\nset -e\npassword_aux="${MARIADB_ROOT_PASSWORD:-}"\nif [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then\n    password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE")\nfi\nif [[ "${MARIADB_REPLICATION_MODE}" != "slave" ]]; then\n    echo "Loading time zones"\n    if command -v mariadb >/dev/null 2>&1; then\n        mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb -u root -p"${password_aux}" mysql\n    else\n        mariadb-tzinfo-to-sql /usr/share/zoneinfo | mysql -u root -p"${password_aux}" mysql\n    fi\nfi'
    echo "$tz_init_script" > /tmp/load_time_zones.sh
    mysql_conf=$'[mysqld]\nskip-name-resolve\nexplicit_defaults_for_timestamp\nbasedir=/usr\nplugin_dir=/usr/lib/mysql/plugin\nport=3306\nsocket=/run/mysqld/mysql.sock\ntmpdir=/tmp\nmax_allowed_packet=16M\nbind-address=*\npid-file=/run/mysqld/mysqld.pid\nlog-error=/var/lib/mysql/mariadb.err\ncharacter-set-server=utf8mb4\nslow_query_log=0\nslow_query_log_file=/var/lib/mysql/mariadb-slow.log\nlong_query_time=10.0\nmax_connections=1200\nconnect_timeout=5\nwait_timeout=600\ntransaction-isolation=READ-COMMITTED\nlower_case_table_names=1\nlog_bin_trust_function_creators=1\n\n[client]\nport=3306\nsocket=/run/mysqld/mysql.sock\ndefault-character-set=UTF8\nplugin_dir=/usr/lib/mysql/plugin\n\n[manager]\nport=3306\nsocket=/run/mysqld/mysql.sock\npid-file=/run/mysqld/mysql.pid'
    echo "$mysql_conf" > /tmp/mariadb_custom.cnf
    echo "### Installing MariaDB helm chart"
    helm upgrade --install mariadb mariadb \
        --namespace "$namespace" \
        --repo https://groundhog2k.github.io/helm-charts/ \
        --version "$MARIADB_CHART_VERSION" \
        --wait \
        --timeout 10m \
        --set settings.rootPassword.value="$DB_ROOT_PASSWORD" \
        --set userDatabase.name.value=gitea \
        --set userDatabase.user.value=gitea \
        --set userDatabase.password.value="$DB_ROOT_PASSWORD" \
        --set storage.requestedSize=5Gi \
        --set image.tag=11.4 \
        --set podSecurityContext=null \
        --set securityContext=null \
        --set-file customScripts."load_time_zones\\.sh"=/tmp/load_time_zones.sh \
        --set-file customConfig=/tmp/mariadb_custom.cnf
    rm /tmp/load_time_zones.sh
    rm /tmp/mariadb_custom.cnf
}

install_nevisadmin4() {
    NEVISADMIN_PASSWORD="${NEVISADMIN_PASSWORD:-$(generate_password)}"
    GIT_USER=root
    GIT_PASSWORD="${GIT_PASSWORD:-$(generate_password)}"
    DB_ROOT_USER=root
    DB_ROOT_PASSWORD="${DATABASE_PASSWORD:-$(generate_password)}"
    DB_APP_PASSWORD="${DATABASE_PASSWORD:-$(generate_password)}"
    DB_SCHEMA_PASSWORD="${DATABASE_PASSWORD:-$(generate_password)}"
    DATABASE_HOST=mariadb
    RELEASE_NAME=nevisadmin4

    if ! oc get namespace "$RELEASE_NAMESPACE" >/dev/null 2>&1; then
        echo "### Creating namespace for nevisAdmin4."
        oc create namespace "$RELEASE_NAMESPACE"
    fi

    echo "### Creating registry secret"
    oc delete secret registry-secret --ignore-not-found  -n "$RELEASE_NAMESPACE"
    oc create secret docker-registry registry-secret --docker-server="$CONTAINER_REGISTRY" --docker-username="$REGISTRY_USERNAME" --docker-password="$REGISTRY_PASSWORD" -n "$RELEASE_NAMESPACE"

    if [ ! -f "neviskey" ]; then
        echo "### Generating private keys for git access"
        ssh-keygen -t ecdsa -C "kubernetes" -m PEM -P "" -f neviskey
    fi

    if ! oc get serviceaccount nevisadmin4-nginx -n "$RELEASE_NAMESPACE" >/dev/null 2>&1; then
        echo "### Creating service account for nginx"
        oc create serviceaccount nevisadmin4-nginx -n "$RELEASE_NAMESPACE"
    fi
    echo "### Assigning privileged scc for ingress-nginx, this is required due the fixed user and capabilities."
    oc adm policy add-scc-to-user privileged -z nevisadmin4-nginx -n "$RELEASE_NAMESPACE"

    echo "### Determining gitea run user based on project UID range."
    # Get the UID range for the namespace
    UID_RANGE=$(oc get project "$RELEASE_NAMESPACE" -o jsonpath='{.metadata.annotations.openshift\.io/sa\.scc\.uid-range}')
    # Extract the lower bound and use that as the user
    if [[ $UID_RANGE == *"/"* ]]; then
      # Format is <start>/<length>
      GITEA_RUN_USER=$(echo "$UID_RANGE" | cut -d'/' -f1)
    else
      # Format is <start>-<end>
      GITEA_RUN_USER=$(echo "$UID_RANGE" | cut -d'-' -f1)
    fi
    echo "### Gitea user is $GITEA_RUN_USER"

    install_mariadb "$RELEASE_NAMESPACE"

    # Has to use the user from openshift
    GIT_REPOSITORY_URL=ssh://$GITEA_RUN_USER@gitea-ssh:2222/$GIT_USER/deploy.git

    echo "### Installing nevisadmin4 helm chart"
    helm upgrade --install $RELEASE_NAME $HELM_INSTALL_PREFIX"nevisadmin4" --create-namespace --wait --timeout 10m -n "$RELEASE_NAMESPACE" \
        --set image.repository="$CONTAINER_REGISTRY" \
        --set git.repositoryUrl=$GIT_REPOSITORY_URL \
        --set git.username=$GIT_USER \
        --set image.imagePullSecretName=registry-secret \
        --set git.password="$GIT_PASSWORD" \
        --set database.host=$DATABASE_HOST \
        --set database.root.username=$DB_ROOT_USER \
        --set database.root.password="$DB_ROOT_PASSWORD" \
        --set nevisAdmin4.database.schemaUserPassword="$DB_SCHEMA_PASSWORD" \
        --set nevisAdmin4.database.applicationUserPassword="$DB_APP_PASSWORD" \
        --set nevisAdmin4.database.enableSSL=false \
        --set nevisAdmin4.domain="$DOMAIN" \
        --set nevisAdmin4.password="$NEVISADMIN_PASSWORD" \
        --set nevisAdmin4.podSecurityContext.fsGroup=null \
        --set bootstrap.nevisAdmin4.enabled=true \
        --set bootstrap.gitea.enabled=true \
        --set gitea.enabled=true \
        --set gitea.ingress.enabled=true \
        --set 'gitea.ingress.hosts[0].host'="$DOMAIN" \
        --set 'gitea.ingress.hosts[0].paths[0].path'="/gitea(/|$)(.*)" \
        --set 'gitea.ingress.hosts[0].paths[0].pathType'=ImplementationSpecific \
        --set 'gitea.ingress.tls[0].hosts[0]'="$DOMAIN" \
        --set 'gitea.ingress.tls[0].secretName'=gitea-tls \
        --set gitea.ingress.annotations."kubernetes\.io/ingress\.class"="nginx-nevisadmin4-$RELEASE_NAMESPACE" \
        --set gitea.gitea.config.server.ROOT_URL=http://"$DOMAIN"/ \
        --set gitea.gitea.config.database.USER=$DB_ROOT_USER \
        --set gitea.gitea.config.database.PASSWD="$DB_ROOT_PASSWORD" \
        --set gitea.gitea.admin.username=$GIT_USER \
        --set gitea.gitea.admin.password="$GIT_PASSWORD" \
	    --set gitea.gitea.config.RUN_USER="\"$GITEA_RUN_USER\"" \
        --set gitea.podSecurityContext.fsGroup="$GITEA_RUN_USER" \
        --set gitea.containerSecurityContext.runAsUser="$GITEA_RUN_USER" \
        --set git.privateKey64="$(cat neviskey | base64 | tr -d '\n')" \
        --set git.publicKey64="$(cat neviskey.pub | base64 | tr -d '\n')" \
        --set git.knownHosts64=UkVQTEFDRV9NRQo= \
        --set nginx.enabled=false \
        --set nginx.controller.scope.enabled=true \
        --set nginx.controller.scope.namespace="$RELEASE_NAMESPACE" \
        --set nginx.controller.ingressClassResource.enabled=false \
        --set nginx.controller.ingressClass=nginx-nevisadmin4-"$RELEASE_NAMESPACE"  \
        --set nginx.controller.ingressClassResource.name=nginx-nevisadmin4-"$RELEASE_NAMESPACE" \
        --set nginx.rbac.scope=true \
        --set nginx.serviceAccount.create=false \
        --set nginx.serviceAccount.name=nevisadmin4-nginx \
        $HELM_SETTINGS

    echo "### Extending nevisAdmin4 configuration with gitea public key for git access"
    helm upgrade nevisadmin4 $HELM_INSTALL_PREFIX"nevisadmin4" --reuse-values --wait -n "$RELEASE_NAMESPACE" \
        --set git.knownHosts64="$(echo gitea-ssh "$(oc exec gitea-0 -c gitea -n "$RELEASE_NAMESPACE" cat /data/ssh/gitea.rsa.pub)" | base64 | tr -d '\n')"

    echo "### Adding ingress-nginx loadbalancer to the installation"
    helm upgrade nevisadmin4 $HELM_INSTALL_PREFIX"nevisadmin4" --reuse-values -n "$RELEASE_NAMESPACE" \
        --set nginx.enabled=true

    echo "### nevisAdmin 4 successfully installed"
    echo "### The following passwords were generated during the installation process:"
    echo "### nevisAdmin 4 'admin' user password: $NEVISADMIN_PASSWORD"
    echo "### Gitea 'root' user password: $GIT_PASSWORD"
    echo "### Database 'root' user password: $DB_ROOT_PASSWORD"
}

upgrade_nevisadmin4() {
    echo "### Upgrading nevisadmin4 helm chart"
    RELEASE_NAME=nevisadmin4
    helm get values $RELEASE_NAME -n $RELEASE_NAMESPACE > old-values.yaml
    helm upgrade $RELEASE_NAME $HELM_INSTALL_PREFIX"nevisadmin4" --create-namespace --wait --timeout 10m -n "$RELEASE_NAMESPACE" \
        -f old-values.yaml $HELM_SETTINGS
}

check_nginx_ip() {
    nginx_service_name="nevisadmin4-nginx-controller"
    iteration_count=60
    sleep_interval=10
    external_ip=""
    port_forward_message="### Until then you can access nevisAdmin 4 using port forwarding by running \"oc port-forward -n $RELEASE_NAMESPACE nevisadmin4-0 28111:9080\", then visiting 127.0.0.1:28111/nevisadmin"

    echo "### Verifying the external IP was assigned to the created nginx loadbalancer."
    for ((i=0; i<iteration_count; i++)); do
        # Get the external IP using oc and JSONPath
        external_ip=$(oc get service "$nginx_service_name" -n "$RELEASE_NAMESPACE" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
        if [[ -n $external_ip ]]; then
            echo "### External IP assigned: $external_ip"
            echo "### Use this IP to create a DNS A record for the domain $DOMAIN, then visit https://$DOMAIN/nevisadmin"
            echo "$port_forward_message"
            return
        fi
        echo "### External IP not assigned yet. Retrying in $sleep_interval seconds..."
        sleep $sleep_interval
    done
    echo "### Timeout: external IP was not assigned within $((iteration_count * sleep_interval)) seconds. On certain Kubernetes clusters the IP assigment of the loadbalancer is not automatic, contact the platform team of the cluster for support."
    echo "### To use a NodePort service and expose nginx directly instead of using a loadbalancer rerun this script with the option '--add-nginx-nodeport'"
    echo "$port_forward_message"
}

add_nginx_node_port() {
    read_release_inputs
    check_helm
    helm_login
    echo "### Adjusting nginx service to use NodePort"
    helm upgrade nevisadmin4 $HELM_INSTALL_PREFIX"nevisadmin4" --reuse-values --wait -n "$RELEASE_NAMESPACE" \
        --set nginx.controller.service.type=NodePort
}

add_nginx_load_balancer() {
    read_release_inputs
    check_helm
    helm_login
    echo "### Adjusting nginx service to use LoadBalancer"
    helm upgrade nevisadmin4 $HELM_INSTALL_PREFIX"nevisadmin4" --reuse-values --wait -n "$RELEASE_NAMESPACE" \
        --set nginx.controller.service.type=LoadBalancer
}

upgrade() {
    read_release_inputs
    push_images
    check_helm
    helm_login
    upgrade_crd
    upgrade_nevisadmin4
}

install() {
    read_inputs
    push_images
    check_helm
    helm_login
    install_cert_manager
    install_crd
    install_nevisadmin4
    check_nginx_ip
}

# by default we pull docker images from Cloudsmith and push them to a container registry
get_images=y

# by default we ask for confirmation
prompt=y

# Parse script arguments
while [[ $# -gt 0 ]]; do
  case "$1" in
    --add-nginx-node-port)
      add_node_port=y
      shift
      ;;
    --add-nginx-load-balancer)
      add_load_balancer=y
      shift
      ;;
    --upgrade)
      upgrade=y
      shift
      ;;
    --namespace)
      if [[ -n $2 ]]; then
        RELEASE_NAMESPACE=$2
        shift
      else
        echo "### Namespace option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --domain)
      if [[ -n $2 ]]; then
        DOMAIN=$2
        shift
      else
        echo "### Domain option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --container-registry)
      if [[ -n $2 ]]; then
        CONTAINER_REGISTRY=$2
        shift
      else
        echo "### Container registry option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --registry-username)
      if [[ -n $2 ]]; then
        REGISTRY_USERNAME=$2
        shift
      else
        echo "### Registry username option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --registry-password)
      if [[ -n $2 ]]; then
        REGISTRY_PASSWORD=$2
        shift
      else
        echo "### Registry password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --cloudsmith-password)
      if [[ -n $2 ]]; then
        CLOUDSMITH_PASSWORD=$2
        shift
      else
        echo "### Cloudsmith password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --helm-repository)
      if [[ -n $2 ]]; then
        HELM_REPOSITORY=$2
        shift
      else
        echo "### Helm repository option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --helm-repository-password)
      if [[ -n $2 ]]; then
        HELM_REPOSITORY_PASSWORD=$2
        shift
      else
        echo "### Helm repository password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --helm-repository-username)
      if [[ -n $2 ]]; then
        HELM_REPOSITORY_USERNAME=$2
        shift
      else
        echo "### Helm repository username option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --cluster-context)
      if [[ -n $2 ]]; then
        CLUSTER_CONTEXT=$2
        shift
      else
        echo "### Cluster context option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --database-password)
      if [[ -n $2 ]]; then
        DATABASE_PASSWORD=$2
        shift
      else
        echo "### Database password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --nevisadmin-password)
      if [[ -n $2 ]]; then
        NEVISADMIN_PASSWORD=$2
        shift
      else
        echo "### Nevisadmin password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --git-password)
      if [[ -n $2 ]]; then
        GIT_PASSWORD=$2
        shift
      else
        echo "### Git password option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --version)
      if [[ -n $2 ]]; then
        VERSION=$2
        shift
      else
        echo "### Version option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --helm-setting)
      if [[ -n $2 ]]; then
        HELM_SETTINGS+="--set $2 "
        shift
      else
        echo "### Helm setting option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --image-version)
      if [[ -n $2 ]]; then
        echo "### Default image version is not supported, set the versions of the individual images by editing the script"
        shift
      else
        echo "### Image version option requires an argument"
        display_usage
        exit 1
      fi
      shift
      ;;
    --skip-images)
      get_images=n
      shift
      ;;
    --no-prompt)
      prompt=n
      shift
      ;;
    --help)
      display_usage
      exit 1
      ;;
    *)
      echo "### Invalid option: $1"
      display_usage
      exit 1
      ;;
  esac
done

echo "### Welcome to the nevisAdmin 4 Kubernetes installer. The installer will deploy nevisAdmin 4 with all it's required dependencies to the cluster."
verify_cluster
if [[ $upgrade == "y" ]]; then
    upgrade
    exit 0
fi
if [[ $add_node_port == "y" ]]; then
    add_nginx_node_port
    exit 0
fi
if [[ $add_load_balancer == "y" ]]; then
    add_nginx_load_balancer
    exit 0
fi
install
