#!/usr/bin/env bash
#
# Copyright (c) 2025, Cloudera, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

SCRIPT_PATH="$(
  cd "$(dirname "$0")" >/dev/null 2>&1 || exit
  pwd -P
)"

DEPLOYMENT_TYPE="local"

args=("${@}")
for i in "${!args[@]}"; do
    case ${args[i]} in
      -p | --profile) PROFILE="${args[i+1]}"; unset args[i]; unset args[i+1] ;;
      -p=* | --profile=*) PROFILE="${args[i]#*=}"; unset args[i] ;;
      docker) DEPLOYMENT_TYPE="docker"; unset args[i] ;; # remove docker from args
      local) DEPLOYMENT_TYPE="local"; unset args[i] ;; # remove local from args
      start | --start) ACTION_START=true ;; # mark as start action
      stop | --stop) ACTION_STOP=true ;; # mark as stop action
      restart | --restart) ACTION_START=true; ACTION_STOP=true ;; # mark as restart action
      -n | --container-name | --instance-name) CMA_INSTANCE_NAME="${args[i+1]}" ;;
      -n=* | --container-name=* | --instance-name=*) CMA_INSTANCE_NAME="${args[i]#*=}" ;;
      -ad | --app-data-dir) CMA_APP_DATA_DIR="${args[i+1]}" ;;
      -ad=* | --app-data-dir=*) CMA_APP_DATA_DIR="${args[i]#*=}" ;;
      --vault) CMA_VAULT=true ;;
      --agent-client-id) CMA_AGENT_CLIENT_ID="${args[i+1]}"; unset args[i]; unset args[i+1] ;;
      --agent-client-id=*) CMA_AGENT_CLIENT_ID="${args[i]#*=}"; unset args[i] ;;
      --agent-client-secret) CMA_AGENT_CLIENT_SECRET="${args[i+1]}"; unset args[i]; unset args[i+1] ;;
      --agent-client-secret=*) CMA_AGENT_CLIENT_SECRET="${args[i]#*=}"; unset args[i] ;;
    esac
done


if [ "${ACTION_START}" = true ]; then
  # add master profile to args if not already present
  if [ -z "${PROFILE}" ]; then
    PROFILE="master"
  else
    if ! [[ "${PROFILE}" =~ "master" ]]; then
      PROFILE+=",master"
    fi
  fi
  master_args=()
  master_args+=(--profile "${PROFILE}")
fi

# create cma-master.conf for docker deployment
create_cma_master_conf_docker() {
  CMA_SERVER_PROFILES=$(get_server_profiles)

  mkdir -p $CMA_SERVER_CONF_DIR
  echo 'Create cma-master.properties ...' | tee -a "$LOG_FILE"
  cat >"${CMA_SERVER_CONF_FILE}" <<EOF
# cma
cma.data.dir=${DATA_DIR}
cma.log.dir=${LOGS_DIR}

# cma server
cma.server.ssl.conf.file=${CMA_SERVER_SSL_CONF_FILE}
cma.client.ssl.conf.file=${CMA_CLIENT_SSL_CONF_FILE}
cma.server.pid.file=${CMA_SERVER_PID_FILE}
cma.server.log.file=${CMA_SERVER_LOG_FILE}
cma.server.profiles=${CMA_SERVER_PROFILES}
EOF

  # secure config file
  chmod 600 ${CMA_SERVER_CONF_FILE}
}

# This function creates the cma-master.conf file for docker deployment
create_cma_master_env_docker() {
  CMA_VERSION=${CMA_VERSION:-$(get_cma_version)}

  mkdir -p $CMA_SERVER_CONF_DIR
  echo 'Create cma-master.env ...' | tee -a "$LOG_FILE"
  cat >"${CMA_SERVER_ENV_FILE}" <<EOF
# This file is generated by the CMA!'
export CMA_VERSION=${CMA_VERSION}
export CMA_UPGRADE_FROM=${CMA_UPGRADE_FROM}
export LC_ALL="en_US.UTF-8"
EOF

  # secure config file
  chmod 600 ${CMA_SERVER_ENV_FILE}
}

# This function is called when the deployment mode is local or not specified
cma_master_local() {
  export CMA_CLI_COMMAND+=" local"
  # call cma-local.sh with the modified args
  ${SCRIPT_PATH}/cma-local.sh "${args[@]}" "${master_args[@]}"
}


# This function is called when the deployment mode is docker
cma_master_docker() {

  CMA_APP_DATA_DIR=${CMA_APP_DATA_DIR:-${HOME}/.cma}
  CMA_INSTANCE_DIR=${CMA_APP_DATA_DIR}/${CMA_INSTANCE_NAME}
  CMA_SERVER_CONF_DIR=${CMA_INSTANCE_DIR}/conf
  CMA_INSTANCE_LOG_DIR=${CMA_INSTANCE_DIR}/logs
  CMA_SERVER_ENV_FILE="${CMA_SERVER_CONF_DIR}/cma-master.env"
  CMA_SERVER_CONF_FILE="${CMA_SERVER_CONF_DIR}/cma-master.properties"

  # create logs directory
  mkdir -p "${CMA_INSTANCE_LOG_DIR}"
  LOG_FILE="$CMA_INSTANCE_LOG_DIR"/$(basename "$0" .sh).log

  if [ "${ACTION_STOP}" = true ]; then

    source "$SCRIPT_PATH"/common.sh # load commons

    if [ -f "${CMA_SERVER_CONF_FILE}" ]; then
      # read the active profiles from cma-master.properties
      ACTIVE_PROFILES=$(get_cma_conf_value "cma.server.profiles" "${CMA_SERVER_CONF_FILE}")
    else
      echo "CMA Master configuration file not found: ${CMA_SERVER_CONF_FILE}"
      ACTIVE_PROFILES=$(get_server_profiles)
    fi

  fi

  if [ "${ACTION_START}" = true ]; then

    #CMA_HOME=/
    CMA_CONTAINER_INSTANCE_DIR=/home/cma/cma-server
    CMA_DATA_DIR=${CMA_CONTAINER_INSTANCE_DIR}/data
    CMA_CONF_DIR=${CMA_CONTAINER_INSTANCE_DIR}/conf
    CMA_LOG_DIR=${CMA_CONTAINER_INSTANCE_DIR}/logs
    CMA_VENV_DIR=${CMA_CONTAINER_INSTANCE_DIR}/venv
    CMA_SERVER_PID_FILE="${CMA_CONTAINER_INSTANCE_DIR}/cma-server.pid"
    CMA_SERVER_SSL_CONF_FILE="${CMA_CONF_DIR}/ssl-server.properties"
    CMA_CLIENT_SSL_CONF_FILE="${CMA_CONF_DIR}/ssl-client.properties"
    CMA_SERVER_LOG_FILE=${CMA_LOG_DIR}/cma-server.log
    VAULT_SERVER_PID_DIR="${CMA_CONTAINER_INSTANCE_DIR}"
    VAULT_SERVER_CONF_DIR="${CMA_SERVER_CONF_DIR}"

    CMA_SERVER_EXTRA_PROFILE="${PROFILE}"
    export CMA_INSTANCE_NAME

    source "$SCRIPT_PATH"/common.sh # load commons

    # create cma-master.properties file
    if [ ! -f "${CMA_SERVER_CONF_FILE}" ]; then
      read_cma_ssl_conf
      create_cma_master_conf_docker
      if [ -n "${SSL_PROFILE}" ]; then
        add_to_active_profiles "${SSL_PROFILE}" "cma.server.profiles"
      fi
    else
      # update profiles with extra profiles
      for profile in $(echo "${CMA_SERVER_EXTRA_PROFILE}" | tr "," " "); do
        add_to_active_profiles "${profile}"
      done
    fi

    # create vault configs file if vault profile is active and the file is missing
    if [ "${CMA_VAULT}" = true ] && [ ! -f "${CMA_VAULT_SERVER_CONF_FILE}" ]; then
      create_cma_vault_server_conf
    fi

    local active_profiles=$(get_cma_conf_value "cma.server.profiles" "${CMA_SERVER_CONF_FILE}")
    if [[ "${active_profiles}" =~ "ssl" ]]; then
      export CMA_SERVER_SSL=true
    fi
    ACTIVE_PROFILES="${active_profiles}"

    # check if DB backup/restore is required
    backup_or_restore_cma_db_if_version_changed

    # create cma-server.env
    if [ ! -f ${CMA_SERVER_ENV_FILE} ]; then
      create_cma_master_env_docker
    else
      if [ -n "${CMA_VERSION}" ] && [ "${CMA_VERSION}" != '' ]; then
        echo "update cma version to ${CMA_VERSION}" | tee -a "$LOG_FILE"
        set_cma_environment_variable_value "CMA_VERSION" ${CMA_VERSION}
      fi

      if [ -n "${CMA_UPGRADE_FROM}" ]; then
        set_cma_environment_variable_value "CMA_UPGRADE_FROM" ${CMA_UPGRADE_FROM}
      fi
    fi

    unset ROOT_DIR
    unset CMA_SERVER_SSL_CONF_FILE
    unset CMA_CLIENT_SSL_CONF_FILE
  fi

  export ACTIVE_PROFILES
  echo "Active profiles: ${ACTIVE_PROFILES}" | tee -a "$LOG_FILE"

  export CMA_SERVER_JAVA_OPTS="${CMA_SERVER_JAVA_OPTS:-"-Xms2g -Xmx4g"}"
  echo "CMA_SERVER_JAVA_OPTS=${CMA_SERVER_JAVA_OPTS}" >>"$LOG_FILE"

  export CMA_CLI_COMMAND+=" docker"
  # call cma-docker.sh with the modified args
  ${SCRIPT_PATH}/cma-docker.sh "${args[@]}" "${master_args[@]}"
}

# call cma-local.sh or cma-docker.sh with the modified args
export CMA_MASTER=true
if [ "${DEPLOYMENT_TYPE}" = "docker" ]; then
  cma_master_docker
elif [ "${DEPLOYMENT_TYPE}" = "local" ]; then
  cma_master_local
fi
