#!/bin/bash 

# function: determineState
#
# parameters
#    none
#
# return
#    0 - state of execution is for an installation
#    1 - state of execution is for an upgrade
#
# function will determine if there is already an installation, thus an upgrade is needed else install

function determineState
{
    CSS_STATE=${INSTALL}

    if [ "${DOCKER_INSTALL}" -eq 1 ]
    then
        determineDockerState
        CSS_STATE=$?
        if [ "${CSS_STATE}" -eq "${INSTALL}" ]
        then
            IGNORE_DB_BACKUP=1
        fi
    elif [ -f "${CSS_HOME}/${APACHE_TOMCAT_CSS_WEBAPPS_CSS_WAR}" ] || [ -d "${CSS_HOME}/${APACHE_TOMCAT_CSS_WEBAPPS}/css" ]
    then
        logPoint "Upgrading existing CSS installation found at ${CSS_HOME}."
        CSS_STATE=${UPGRADE}
    else 
        logPoint "Installing new CSS instance at ${CSS_HOME} because ${CSS_HOME}/${APACHE_TOMCAT_CSS_WEBAPPS_CSS_WAR} was not found."
        logPoint "If you wanted to upgrade, choose N and check the CSS_HOME property in your config file."
        logPoint "If the war has already been deleted, choose N and run the command {mkdir -p ${CSS_HOME}/apache-tomcat-css/webapps && echo > ${CSS_HOME}/${APACHE_TOMCAT_CSS_WEBAPPS_CSS_WAR}}"
        IGNORE_DB_BACKUP=1
    fi    
    logPoint "Verify the installation mode above."
    if [ "${PREREQ_MODE}" -eq 1 ]
    then
        logPoint "Running in prereq mode. Nothing will be changed. The prompt is to assist in verification of the mode selected by the installer."
    fi
    goOrStop 
    return "${CSS_STATE}"
}

# function: prepareSoftware
#
# parameters
#    none
#
# return
#    none
#
# function will determine if the CSS software needs to be downloaded or unpackaged and ready for installation

function prepareSoftware
{

    PREPARE_RC=0
    NO_OF_ZIPS=$(2>/dev/null ls "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip | wc -l)
    
    # CSS_VERSION will be like 6.5.0.0.150, so it contains 5 numbers.
    # it will always be lower case by here.
    if [ "${DESIRED_VERSION}" != "latest" ]
    then
        if [ "$NO_OF_ZIPS" -eq 1 ]
        then
            logPoint "Existing CSS zip found. Extracting it to verify the version."
            cleanTempAndUnzip ignore
            if [[ "${CSS_VERSION}" == "${DESIRED_VERSION}"* ]]
            then
                logPoint "Existing CSS zip matched version ${DESIRED_VERSION}."
            elif variableEmpty "${CSS_VERSION}"
            then
                logPoint "Removing corrupt CSS zip."
                rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}"
            else
                logPoint "Existing CSS zip version ${CSS_VERSION} did not match version ${DESIRED_VERSION}. Deleting it and attempting to download the correct version."
                rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}"
            fi
        elif [ "$NO_OF_ZIPS" -ne 0 ]
        then
            logPoint "Multiple CSS zip files located. Deleting them and attempting to download the correct version."
            rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}" 
        fi
        NO_OF_ZIPS=$(2>/dev/null ls "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip | wc -l)
        if [ "$NO_OF_ZIPS" -eq 0 ]
        then
            logPoint "Downloading version ${DESIRED_VERSION} of CSS software from flexagon.com"

            # get the specified version of the software from the site
            wget -O "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/"${TOMCAT_COMPLETE_ZIP_FILE_NAME}" "${CSS_ALT_SOFTWARE_DOWNLOAD_URL}" --timeout=12 --tries=1 > /dev/null 2>&1
            DOWNLOAD_RC=$?
            if [ ${DOWNLOAD_RC} -ne 0 ]
            then
                # If the download fails, then delete the blank file that we get.
                rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/"${TOMCAT_COMPLETE_ZIP_FILE_NAME}" > /dev/null 2>>"${LOG_FILE}" 
                generateFatalErrorMessage 121 "${DESIRED_VERSION}" "${CSS_ALT_SOFTWARE_DOWNLOAD_URL}" "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/"${TOMCAT_COMPLETE_ZIP_FILE_NAME}"
                exit ${DOWNLOAD_RC}
            fi
            cleanTempAndUnzip final
        fi
        if [[ "$DESIRED_VERSION" == "1"* ]]
        then
          DOCKER_REPO=flexagon.azurecr.io/
        else
          DOCKER_REPO=
        fi
    else
        logPoint "Installing the latest CSS version was requested."
        DOCKER_REPO=flexagon.azurecr.io/
        setLatestVersion
        NO_INTERNET=$?
        if [ ${NO_INTERNET} -eq 0 ]
        then
            logPoint "The latest CSS version is ${LATEST_VERSION}."
        fi
        if [ "$NO_OF_ZIPS" -eq 1 ]
        then
            logPoint "Existing zip file found. Extracting to see if it matches the latest available version."
            cleanTempAndUnzip ignore
            
            if [ "${LATEST_VERSION}" != "0" ] && [[ "${CSS_VERSION}" == "${LATEST_VERSION}"* ]]
            then
                logPoint "Existing CSS zip matched version ${LATEST_VERSION}."
            elif variableEmpty "${CSS_VERSION}"
            then
                logPoint "Removing corrupt CSS zip."
                rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}"
            elif [ "${LATEST_VERSION}" = "0" ]
            then
                logPoint "Existing CSS zip version ${CSS_VERSION} was found. The latest version was not able to be checked from Flexagon.com. To continue the installer with version ${CSS_VERSION}, press Y. To stop the installer press N."
                goOrStop
            else
                logPoint "Existing CSS zip version ${CSS_VERSION} did not match version ${LATEST_VERSION}. Deleting it and attempting to download the correct version."
                rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}"
            fi
        elif [ "$NO_OF_ZIPS" -ne 0 ]
        then
            logPoint "Multiple CSS zip files located. Deleting them and attempting to download the correct version."
            rm -f "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip > /dev/null 2>>"${LOG_FILE}"
        fi
        NO_OF_ZIPS=$(2>/dev/null ls "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/*.zip | wc -l)
        if [ "$NO_OF_ZIPS" -eq 0 ]
        then
            logPoint "No existing zips found. Downloading latest CSS software from flexagon.com"

            # get the latest version of the software from the site
            #No zip file, DESIRED_VERSION was latest, so attempt to download the latest.
            wget -O "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/"${TOMCAT_COMPLETE_ZIP_FILE_NAME}" "${CSS_SOFTWARE_DOWNLOAD_URL}" --timeout=12 --tries=1 > /dev/null 2>&1
            DOWNLOAD_RC=$?
            if [ ${DOWNLOAD_RC} -ne 0 ]
            then
                generateFatalErrorMessage 122 "${CSS_SOFTWARE_DOWNLOAD_URL}" "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}"/"${TOMCAT_COMPLETE_ZIP_FILE_NAME}"
                exit ${DOWNLOAD_RC}
            fi
            cleanTempAndUnzip final
        fi        
    fi

}

# function: cleanTempAndUnzip
#
# parameters
#    $1 - "ignore" will prevent fatal error message 133 from being thrown.
function cleanTempAndUnzip
{
    logPoint "Removing already unpacked CSS software"
    rm -rf "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}" > /dev/null 2>>"${LOG_FILE}"
    PREPARE_RC=$?
    if [ ${PREPARE_RC} -ne 0 ]
    then
        generateFatalErrorMessage 120 "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"
    else
        setupMountPointArrays # reset free space after this as it has increased.
        logPoint "Checking for space to extract CSS software in ${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"
        createDirectory "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"
        requireGbFree "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}" 3

        logPoint "Unpackaging CSS software to ${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"
        # unzip the download
        unzipper "${INSTALLER_DOWNLOADS_SOFTWARE_DIRECTORY}" "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}" "$1"
        setupMountPointArrays # reset free space after this as it has decreased.
        PREPARE_RC=$?
        
        # following call will derive CSS_VERSION from the zip file found.
        setZipCSSVersion
    fi
}



# function: testOrUpdateContextFile
#
# parameters
#    $1 Prereq Mode
#
# return
#    none
#
# function will configure the context.xml file based on database type, install/upgrade
# or the MAINTAIN_EXISTING_CONTEXT_FILE.  If maintain existing, the context file will be copied from
# the backup

function testOrUpdateContextFile
{
    # setup the source and target paths for the context file
    if isOracleDatabase
    then
        SOURCE_DIR=${INSTALLER_TEMP_SOFTWARE_DIRECTORY}/${APACHE_TOMCAT_CSS_CONF}
        SOURCE_FILE=${CONTEXT_XML_ORACLE}
    else
        SOURCE_DIR=${INSTALLER_TEMP_SOFTWARE_DIRECTORY}/${APACHE_TOMCAT_CSS_CONF}
        SOURCE_FILE=${CONTEXT_XML_POSTGRES}
    fi
    TARGET_DIR=${CSS_HOME}/${APACHE_TOMCAT_CSS_CONF}
    TARGET_FILE=${TOMCAT_CONTEXT_XML}

    if [ "${1}" -eq 1 ] && [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ]
    then
        TARGET_DIR=${INSTALLER_TEMP_CONFIG_DIRECTORY}
    elif [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ] && [ "${MAINTAIN_EXISTING_CONTEXT_FILE}" -eq 1 ]
    then
        SOURCE_DIR=${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS_CONF}
        SOURCE_FILE=${TOMCAT_CONTEXT_XML}
    fi

    # copy is a lcl function that handles mkdir and cp
    copy "${SOURCE_DIR}" "${SOURCE_FILE}" "${TARGET_DIR}" "${TARGET_FILE}"

    prompt "Enter CSS ${CSS_DB_USER} password" "${CSS_DB_PASSWORD}"
    CSS_DB_PASSWORD=${PROMPT_VALUE}


    if [ "${MAINTAIN_EXISTING_CONTEXT_FILE}" -eq 0 ] || [ "${EXECUTION_STATE}" -eq "${INSTALL}" ]
    then
    # adjust the properties in the context.xml file based on the cssinstaller_config.txt inputs
        sed -i "s|url=".*"|url=\"${DATABASE_URL}\"|g" "${TARGET_DIR}"/"${TARGET_FILE}"
        sed -i "s|user=".*"|user=\"${CSS_DB_USER}\"|g" "${TARGET_DIR}"/"${TARGET_FILE}"

        # Need to regex escape the pw before trying to put it in the file.
        ESCAPED_CSS_DB_PASSWORD=$(printf '%s\n' "$CSS_DB_PASSWORD" | sed -e 's/[\/&]/\\&/g')
        sed -i "s|password=".*"|password=\"${ESCAPED_CSS_DB_PASSWORD}\"|g" "${TARGET_DIR}"/"${TARGET_FILE}"
    fi

    if [ "${1}" -eq 1 ] && [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ]
    then
        # check for user changes
        diff -Bbw "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_CONF}"/"${TARGET_FILE}" "${INSTALLER_TEMP_CONFIG_DIRECTORY}"/"${TARGET_FILE}" > "${LOG_DATA_FILE}" 2>>"${LOG_FILE}"
        DIFF_RC=$?

        if [ ${DIFF_RC} -ne 0 ]
        then
            logPoint "MAINTAIN_EXISTING_CONTEXT_FILE is currently set to ${MAINTAIN_EXISTING_CONTEXT_FILE}"
            if [ "${MAINTAIN_EXISTING_CONTEXT_FILE}" -eq 1 ]
            then
                # adjust the < and > symbols in the file to be readable
                sed -i "s|^<|Your Config: |g" "${LOG_DATA_FILE}"
                sed -i "s|^>|Not applied: |g" "${LOG_DATA_FILE}"
                generateWarningErrorMessage 128 "context.xml"
            else
                # adjust the < and > symbols in the file to be readable
                sed -i "s|^<|Current Data: |g" "${LOG_DATA_FILE}"
                sed -i "s|^>|Future  Data: |g" "${LOG_DATA_FILE}"
                generateWarningErrorMessage 109 "context.xml"
            fi           
        fi
        rm -f "${INSTALLER_TEMP_CONFIG_DIRECTORY}"/"${TARGET_FILE}"
    fi
}

# function: testOrUpdateServerFile
#
# parameters
#    $1 prereq mode
#
# return
#    none
#
# function will configure the server.xml file based on install/upgrade
# or the MAINTAIN_EXISTING_SERVER_FILE.  If maintain existing, the server file will be copied from
# the backup

function testOrUpdateServerFile
{
    SOURCE_DIR=${INSTALLER_TEMP_SOFTWARE_DIRECTORY}/${APACHE_TOMCAT_CSS_CONF}
    SOURCE_FILE=${TOMCAT_SERVER_XML}

    TARGET_DIR=${CSS_HOME}/${APACHE_TOMCAT_CSS_CONF}
    TARGET_FILE=${TOMCAT_SERVER_XML}

    if [ "${1}" -eq 1 ] && [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ]
    then
        TARGET_DIR=${INSTALLER_TEMP_CONFIG_DIRECTORY}
    elif [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ] && [ "${MAINTAIN_EXISTING_SERVER_FILE}" -eq 1 ]
    then
        SOURCE_DIR=${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS_CONF}
    fi

    # copy is a lcl function that handles mkdir and cp
    copy "${SOURCE_DIR}" "${SOURCE_FILE}" "${TARGET_DIR}" "${TARGET_FILE}"

    # adjust the CSS port if needed
    if [ "${MAINTAIN_EXISTING_SERVER_FILE}" -eq 0 ] || [ "${EXECUTION_STATE}" -eq "${INSTALL}" ]
    then
      sed -i "s|8001|${CSS_PORT}|g" "${TARGET_DIR}"/"${TARGET_FILE}"
    fi

    if [ "${1}" -eq 1 ] && [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ]
    then
        # check for user changes
        diff -Bbw "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_CONF}"/"${TARGET_FILE}" "${INSTALLER_TEMP_CONFIG_DIRECTORY}"/"${TARGET_FILE}" > "${LOG_DATA_FILE}" 2>>"${LOG_FILE}"
        DIFF_RC=$?

        if [ ${DIFF_RC} -ne 0 ]
        then
            
            
            logPoint "MAINTAIN_EXISTING_SERVER_FILE is currently set to ${MAINTAIN_EXISTING_SERVER_FILE}"
            if [ "${MAINTAIN_EXISTING_SERVER_FILE}" -eq 1 ]
            then
                # adjust the < and > symbols in the file to be readable
                sed -i "s|^<|Your Config: |g" "${LOG_DATA_FILE}"
                sed -i "s|^>|Not applied: |g" "${LOG_DATA_FILE}"
                generateWarningErrorMessage 127 "server.xml"
            else
                # adjust the < and > symbols in the file to be readable
                sed -i "s|^<|Current Data: |g" "${LOG_DATA_FILE}"
                sed -i "s|^>|Future  Data: |g" "${LOG_DATA_FILE}"
                generateWarningErrorMessage 111 "server.xml"
            fi
            
        fi
        rm -f "${INSTALLER_TEMP_CONFIG_DIRECTORY}"/"${TARGET_FILE}"
    fi
}

# function: backupCurrentInstallation
#
# parameters
#    none
#
# return
#    none
#
# function will backup the current installation if this is for an upgrade and not in prereq mode (running prerequisites without install),
# also makes sure that it is only backed up once per day

function backupCurrentInstallation
{
    # docker doesn't utilize libext so we need to source the driver from the temp location, just like prereqs
	
    # since an upgrade, backup the working installation, only do this if not PREREQ_MODE and not DOCKER_INSTALL
    if [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ] && [ "${PREREQ_MODE}" -eq 0 ] && [ "${DOCKER_INSTALL}" -eq 0 ]
    then
        # --------------- BACKUP apache-tomcat-css ---------------
        # check if a backup already exists for the version
        if [ -d "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}"/"${APACHE_TOMCAT_CSS}" ]
        then
            logPoint "A backup already exists (${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS}), no backup created"
        else
            logPoint "Deleting the temp folder under ${CSS_HOME}"/"${APACHE_TOMCAT_CSS} before back up"
            rm -rf "${CSS_HOME}"/"${APACHE_TOMCAT_CSS}"/temp
            logPoint "Deleted temp folder from ${CSS_HOME}"/"${APACHE_TOMCAT_CSS}"
            
            # copy the current tomcat installation
            logPoint "Backing up Tomcat installation from ${CSS_HOME}/${APACHE_TOMCAT_CSS} to ${UPGRADE_BACKUP_TOMCAT_DIRECTORY}"
            cp -r "${CSS_HOME}"/"${APACHE_TOMCAT_CSS}" "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}"
		fi
        
        # printing details of libext folder for our reference. could be useful during support
        logPoint "listing of files in ${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS}"
        ls -ltr "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS}" | tee -a "${LOG_FILE}"
        logPoint "listing of files in ${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS_LIBEXT}"
        ls -ltr "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS_LIBEXT}" | tee -a "${LOG_FILE}"
        
        # --------------- BACKUP apache-tomcat-css ---------------
    fi
    
    # do the following block for upgrade AND upgrade_WLS, but not install. and not PREREQ_MODE
    if [ "${EXECUTION_STATE}" -ne "${INSTALL}" ] && [ "${PREREQ_MODE}" -eq 0 ]
    then

        # save current directory so we can restore back
        CURRENT_PWD=$(pwd)

        # --------------- BACKUP Artifacts Repository ---------------
        if [ -f "${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}"/artifacts.tar.gz ]
        then
            logPoint "A backup already exists (${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}/artifacts.tar.gz), no backup created"
        else 
            if [ "${IGNORE_ARTIFACT_BACKUP}" -eq 0 ]
            then
                # must cd in to repository folder, so we can restore in same manner without any additional folders
                cd "${ARTIFACT_REPOSITORY_DIRECTORY}"
                ARTIFACTS_EXIST=$?
                if [ ${ARTIFACTS_EXIST} -eq 0 ]
                then
                    # copy the artifacts
                    logPoint "Backing up the artifacts directory from ${ARTIFACT_REPOSITORY_DIRECTORY} to ${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}, may take some time"
                    tar -czf "${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}"/artifacts.tar.gz *  >> "${LOG_FILE}" 2>&1
                    T_RC=$?
                    if [ ${T_RC} -ne 0 ]
                    then
                        # delete the artifacts backup file.
                        rm -f "${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}"/artifacts.tar.gz >> "${LOG_FILE}" 2>&1						
                        generateFatalErrorMessage 135 "${ARTIFACT_REPOSITORY_DIRECTORY}" "${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}"
                    else
                        chownForDockerCSSHome "${UPGRADE_BACKUP_ARTIFACTS_DIRECTORY}/artifacts.tar.gz"
                    fi
                else
                    logPoint "No artifacts found at ${ARTIFACT_REPOSITORY_DIRECTORY}."
                    generateFatalErrorMessage 137 "${ARTIFACT_REPOSITORY_DIRECTORY}"
                fi
            else
                logPoint "Skipping backing up the artifacts directory as requested."
            fi
        fi
        #Don't check the size again for this.
        SKIP_ARTIFACT_SIZE_CHECK=1
        # --------------- BACKUP Artifacts Repository ---------------
        
        # --------------- BACKUP plugins folder  ---------------
        if [ -f "${UPGRADE_BACKUP_PLUGINS_DIRECTORY}"/plugins.tar.gz ]
        then
            logPoint "A backup already exists (${UPGRADE_BACKUP_PLUGINS_DIRECTORY}/plugins.tar.gz), no backup created"
        else        
            logPoint "Backing up the plugins directory from ${WORKING_DIRECTORY}/plugins to ${UPGRADE_BACKUP_PLUGINS_DIRECTORY}, may take some time"

            # must cd in to plugins folder, so we can restore in same manner without any additional folders
            cd "${WORKING_DIRECTORY}"/plugins
            PLUGINS_EXIST=$?
            if [ ${PLUGINS_EXIST} -eq 0 ]
            then
                tar -czf "${UPGRADE_BACKUP_PLUGINS_DIRECTORY}"/plugins.tar.gz * >> "${LOG_FILE}" 2>&1
                T_RC=$?
                if [ ${T_RC} -ne 0 ]
                then 
                    generateFatalErrorMessage 135 "${WORKING_DIRECTORY}"/plugins "${UPGRADE_BACKUP_PLUGINS_DIRECTORY}"
                else
                    chownForDockerCSSHome "${UPGRADE_BACKUP_PLUGINS_DIRECTORY}/plugins.tar.gz"
                fi
            else
                logPoint "No plugins found at ${WORKING_DIRECTORY}/plugins."
                logPoint "This is expected for older versions of CSS which stored them in the database instead."
            fi
        fi
        #don't check the size again after this.
        SKIP_PLUGIN_SIZE_CHECK=1
        # --------------- BACKUP plugins folder  ---------------

        # go back to original directory
        cdOrFail "${CURRENT_PWD}"

        # --------------- BACKUP database ---------------
        if [ "${IGNORE_DB_BACKUP}" -eq 0 ]
        then
            # backup the database schemas
            logPoint "Backing up the database schemas, this may take some time"

            prompt "Enter database system password" "${SYSTEM_DB_PASSWORD}"
            SYSTEM_DB_PASSWORD=${PROMPT_VALUE}

            if variableEmpty "${BACKUP_DATABASE_DIRECTORY}"
            then
                "${CSS_JAVA_HOME}"/bin/java -cp "${DB_UTIL_CLASSPATH}" flexagon.css.installer.DatabaseManagement -OPERATION BACKUP -URL "${DATABASE_URL}" -DB_USERNAME "${SYSTEM_DB_USER}" -DB_PASSWORD "${SYSTEM_DB_PASSWORD}" -LOG_FILE "${LOG_FILE}"
            else
                "${CSS_JAVA_HOME}"/bin/java -cp "${DB_UTIL_CLASSPATH}" flexagon.css.installer.DatabaseManagement -OPERATION BACKUP -URL "${DATABASE_URL}" -DB_USERNAME "${SYSTEM_DB_USER}" -DB_PASSWORD "${SYSTEM_DB_PASSWORD}" -BACKUP_DIR "${BACKUP_DATABASE_DIRECTORY}" -LOG_FILE "${LOG_FILE}"
            fi
            DB_UTIL_RC=$?
            handleDbError ${DB_UTIL_RC} "${SYSTEM_DB_USER}"
        else
            logPoint "No database backup created as requested."
        fi
        # --------------- BACKUP database ---------------
	fi
}

# function: manageSetEnvOverride
#
# parameters
#    none
#
# return
#    none
#
# function will manage the setupoverride file with configuration details

function manageSetEnvOverride
{
    # always set it as exists by default
	SETENVOVERRIDE_FILE_EXISTS=1
	
    # use the setenv.sh and setenvoverride.sh script if there is one present in the backups
    if [ -f "${UPGRADE_BACKUP_CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" ]
    then
        cp "${UPGRADE_BACKUP_CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" > /dev/null 2>>"${LOG_FILE}"
        # the setenvoverride java home should match the one we are using. If not, update it now.
        if ! grep CSS_JAVA_HOME "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" > /dev/null 2>>"${LOG_FILE}"
        then
            logPoint "Updating the Java Home for CSS."
            if ! grep "^JAVA_HOME=.*" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" > /dev/null 2>>"${LOG_FILE}"
            then
              # if JAVA_HOME was not set before, set it now.
              echo >> "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"
              echo "JAVA_HOME=${CSS_JAVA_HOME}" >> "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"

            else
              # if it was, update it.
              sed -i "s|^JAVA_HOME=.*|JAVA_HOME=${CSS_JAVA_HOME}|g" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"
            fi
        fi
    else
        # if there is no file or this is a new installation, use the files from the download and adjust per the cssinstaller_config.txt file
        if [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ] && [ ! -f "${UPGRADE_BACKUP_CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}" ]
        then
            generateWarningErrorMessage 112

            # set a flag so that we can not start the server if the file didn't exist and explain how to fix this
            SETENVOVERRIDE_FILE_EXISTS=0
    	fi

        # adjust the file per the cssinstaller_config.txt file
        sed -i "s|CSS_APPLICATION_DIRECTORY=".*"|CSS_APPLICATION_DIRECTORY=${WORKING_DIRECTORY}|g" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"
        sed -i "s|CSS_ARTIFACTS_DIRECTORY=".*"|CSS_ARTIFACTS_DIRECTORY=${ARTIFACT_REPOSITORY_DIRECTORY}|g" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"
        sed -i "s|#JAVA_HOME=".*"|JAVA_HOME=${CSS_JAVA_HOME}|g" "${CSS_TOMCAT_BIN_DIRECTORY}"/"${SETENVOVERRIDE_FILE_NAME}"
    fi
}

# function: manageDatabaseDownloads
#
# parameters
#    none
#
# return
#    none
#
# function will make sure the appropriate database driver is configured
# and setup up any necessary wallets

function manageDatabaseDownloads
{
    # only need to adjust if an oracle database
    
    if isOracleDatabase
    then
        logPoint "Preparing the new oracle database driver"
    fi
    
    # remove any existing expanded files
    # delete everything in INSTALLER_TEMP_DRIVER_DIRECTORY and then unzip again.
    rm -rf "${INSTALLER_TEMP_DRIVER_DIRECTORY}"/* >> "${LOG_FILE}" 2>&1

    # un tar the downloaded oracle driver
    tar xf "${CSS_INSTALLER_HOME}"/scripts/jars/ojdbc8*.gz -C "${INSTALLER_TEMP_DRIVER_DIRECTORY}" > /dev/null 2>>"${LOG_FILE}"
    T_RC=$?
    if [ ${T_RC} -ne 0 ]
    then 
        generateFatalErrorMessage 134 "${CSS_INSTALLER_HOME}"/scripts/jars/ojdbc8*.gz  "${INSTALLER_TEMP_DRIVER_DIRECTORY}"
    fi

    # check to see if a database wallet has been downloaded
    ls "${INSTALLER_DOWNLOADS_WALLETS_DIRECTORY}"/*.zip > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
        NUM_OF_ZIPS=$(ls "${INSTALLER_DOWNLOADS_WALLETS_DIRECTORY}"/*.zip | wc -l)
    else
        # no zip files in wallet download
        NUM_OF_ZIPS=0
    fi

    if [ "${NUM_OF_ZIPS}" -gt 0 ]
    then
        logPoint "Preparing the oracle wallet files"
        for WALLET in $(ls "${INSTALLER_DOWNLOADS_WALLETS_DIRECTORY}"/*.zip)
        do
            # get the filename so we can use it as a base folder
            WALLET_NAME=$(basename "${WALLET}" | cut -f1 -d'.')
            logPoint "Preparing wallet ${WALLET} for use."
            # remove any existing files and unzip the wallet
            rm -rf "${CSS_DATABASE_WALLET_DIRECTORY}"/"${WALLET_NAME}" > /dev/null 2>>"${LOG_FILE}"
            unzip "${WALLET}" -d "${CSS_DATABASE_WALLET_DIRECTORY}/${WALLET_NAME}" > /dev/null 2>>"${LOG_FILE}"
            chownForDockerCSSHome "${CSS_DATABASE_WALLET_DIRECTORY}/${WALLET_NAME}" 1
            logPoint "Wallet ${WALLET_NAME} prepared for use."
        done
    fi

}

# function: manageDatabaseObjects
#
# parameters
#    none
#
# return
#    none
#
# function will make sure the appropriate database driver is configured

function manageDatabaseObjects
{
    # need to make calls to either create the schemas (install) or update the schemas (upgrade)
    if [ "${EXECUTION_STATE}" -eq "${INSTALL}" ]
    then
        logPoint "Creating the database objects"

        prompt "Enter CSS ${CSS_DB_USER} password" "${CSS_DB_PASSWORD}"
        CSS_DB_PASSWORD=${PROMPT_VALUE}

        prompt "Enter database system password" "${SYSTEM_DB_PASSWORD}"
        SYSTEM_DB_PASSWORD=${PROMPT_VALUE}

		"${CSS_JAVA_HOME}"/bin/java -cp "${DB_UTIL_CLASSPATH}" flexagon.css.installer.DatabaseManagement -OPERATION INSTALL -URL "${DATABASE_URL}" -DB_USERNAME "${SYSTEM_DB_USER}" -DB_PASSWORD "${SYSTEM_DB_PASSWORD}" -INSTALL_DIR "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}" -SCHEMA_PASSWORD "${CSS_DB_PASSWORD}" -LOG_FILE "${LOG_FILE}"	 -FD_ADMIN "${CSS_DB_USER}"
	    DB_UTIL_RC=$?
	else
		logPoint "Updating the database objects"

        prompt "Enter CSS ${CSS_DB_USER} password" "${CSS_DB_PASSWORD}"
        CSS_DB_PASSWORD=${PROMPT_VALUE}

        prompt "Enter database system password" "${SYSTEM_DB_PASSWORD}"
        SYSTEM_DB_PASSWORD=${PROMPT_VALUE}

		"${CSS_JAVA_HOME}"/bin/java -cp "${DB_UTIL_CLASSPATH}" flexagon.css.installer.DatabaseManagement -OPERATION UPGRADE -URL "${DATABASE_URL}" -DB_USERNAME "${SYSTEM_DB_USER}" -DB_PASSWORD "${SYSTEM_DB_PASSWORD}" -INSTALL_DIR "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}" -SCHEMA_PASSWORD "${CSS_DB_PASSWORD}" -LOG_FILE "${LOG_FILE}" -FD_ADMIN "${CSS_DB_USER}"
	        DB_UTIL_RC=$?
	fi
	handleDbError ${DB_UTIL_RC}
	return ${DB_UTIL_RC}
}


# function: copyPlugin
#
# parameters
#    none
#
# return
#    none
#
# function will copy plugins from plugin temp directory from new install to working directory for auto upload process
function copyPlugins
{
    # copy plugin files
    logPoint "Copying new plugins from ${INSTALLER_TEMP_SOFTWARE_PLUGINS_DIRECTORY} to ${WORKING_DIRECTORY} for auto upload"
    cp -r  "${INSTALLER_TEMP_SOFTWARE_PLUGINS_DIRECTORY}" "${WORKING_DIRECTORY}"
    chownForDockerCSSHome "${WORKING_DIRECTORY}/plugins" 1
}


# function: installCSSDocker
#
# parameters
#    none
#
# return
#    0 - software installed
#    1 - install failed
#
# function will start the installation of the downloaded software
function installCSSDocker
{
    # DOCKER INSTALL
    if [ "${EXECUTION_STATE}" -ne "${INSTALL}" ]
    then
        logPoint "Beginning Docker Upgrade."
    
        deleteDockerContainer
    else
        logPoint "Beginning Docker Install."
    fi
    
    # Manage database objects. Execute install or migration scripts
    manageDatabaseObjects
    
    # Copy plugins to working directory
    copyPlugins
    
    # Pull docker image based on target version
    pullDockerImage
    
    # Run docker container with updated image
    runDockerContainer
    
    logPoint "Docker Install Complete"
}

# function: installCSS
#
# parameters
#    none
#
# return
#    0 - software installed
#    1 - install failed
#
# function will start the installation of the downloaded software

function installCSS
{
    #Database first so that if it fails it won't try to upgrade next time.
    manageDatabaseObjects
    #Do this for install and upgrade_wls.
    if [ "${EXECUTION_STATE}" -ne "${UPGRADE}" ]
    then
        logPoint "Copying new software to ${CSS_HOME}"
        cp -r "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"/* "${CSS_HOME}" || exitFatalErrorMessage 144 "${CSS_HOME}"

        # remove these directories to keep  the server folder clean, let them get added back based on the cssinstaller_config file
        rm -rf "${CSS_HOME}"/database >> "${LOG_FILE}" 2>&1 || exitFatalErrorMessage 143 "${CSS_HOME}"/database
        rm -rf "${CSS_HOME}"/application >> "${LOG_FILE}" 2>&1 || exitFatalErrorMessage 143 "${CSS_HOME}"/application
        rm -rf "${CSS_HOME}"/artifacts >> "${LOG_FILE}" 2>&1 || exitFatalErrorMessage 143 "${CSS_HOME}"/artifacts
        
        # just in case the default directories are being used, lets make sure they are created
        createDirectory "${WORKING_DIRECTORY}"
        createDirectory "${ARTIFACT_REPOSITORY_DIRECTORY}" 
    else
        logPoint "Removing ${CSS_HOME}/${APACHE_TOMCAT_CSS} folder"
        rm -rf "${CSS_HOME}"/"${APACHE_TOMCAT_CSS}" >> "${LOG_FILE}" 2>&1 || tomcatDirDeleteFailedDuringUpgrade
        
        logPoint "Copying new apache-tomcat-css software from ${INSTALLER_TEMP_SOFTWARE_DIRECTORY}/${APACHE_TOMCAT_CSS} to ${CSS_HOME}"

        cp -r "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"/"${APACHE_TOMCAT_CSS}" "${CSS_HOME}" || exitFatalErrorMessage 144 "${CSS_HOME}"
        # due to needing this line above for the java calls, the remove 2 lines above cleans out all file systems so after the rm
        # we need to re-copy this libext so this is duplicated for a reason.  We want the database work to be one of the first things done, do not remove
        stat -t "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}"/"${APACHE_TOMCAT_CSS_LIBEXT}"/* >/dev/null 2>&1 && (cp "${UPGRADE_BACKUP_TOMCAT_DIRECTORY}"/"${APACHE_TOMCAT_CSS_LIBEXT}"/* "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}" || exitFatalErrorMessage 144 "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}")
        
        # copy all files from the base folder (scripts, ...) and not directories so don't want a -r on this one,
        # not dumping to the logs because error indicates to add the -r and not on this one.
        cp "${INSTALLER_TEMP_SOFTWARE_DIRECTORY}"/* "${CSS_HOME}" > /dev/null 2>&1
    fi
    
    # copy plugin files to the configured directory
    copyPlugins
    
    # decided to copy Oracle driver in libext for all customers and remove lib/ojdbc*.jar for all customers even PostgreSQL
    if [ "${EXECUTION_STATE}" -eq "${UPGRADE}" ]
    then
        logPoint "Updating oracle driver jars in ${CSS_HOME}/${APACHE_TOMCAT_CSS_LIBEXT} with the version shipped with the installer."
        stat -t "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}"/*ojdbc6*.jar >/dev/null 2>&1 && logPoint "Removing any old ojdbc jars from ${CSS_HOME}/${APACHE_TOMCAT_CSS_LIBEXT}"
        stat -t "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}"/*ojdbc7*.jar >/dev/null 2>&1 && logPoint "Removing any old ojdbc jars from ${CSS_HOME}/${APACHE_TOMCAT_CSS_LIBEXT}"
        rm -f "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}"/*ojdbc*.jar 2>/dev/null
    fi
    
    # before copy make sure we are able to write the jars in libext folder
    chmod u+w ${CSS_HOME}/${APACHE_TOMCAT_CSS_LIBEXT}/*
    cp "${INSTALLER_TEMP_DRIVER_DIRECTORY}"/*/*.jar "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIBEXT}" >> "${LOG_FILE}" 2>&1 || exitFatalErrorMessage 150

    # remove the current ojdbc jars
    stat -t "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIB}"/*ojdbc*.jar >/dev/null 2>&1 && logPoint "Removing ojdbc driver files from ${CSS_HOME}/${APACHE_TOMCAT_CSS_LIB}."
    rm -f "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LIB}"/*ojdbc*.jar >> "${LOG_FILE}" 2>&1
     
    logPoint "Updating the context.xml file for Tomcat"
    testOrUpdateContextFile 0

    logPoint "Updating the server.xml file for Tomcat"
    testOrUpdateServerFile 0

    logPoint "Managing setenvoverride"
    manageSetEnvOverride

    logPoint "Updating script permissions"
    chmod +x "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_BIN}"/*.sh
    chmod +x "${CSS_HOME}"/*.sh

}

# function: startCSS
#
# parameters
#    none
#
# return
#    none
#
# function will start the tomcat server

function startCSS
{
    # start the tomcat server
    CURRENT_PWD=$(pwd)
    cdOrFail "${CSS_HOME}/${APACHE_TOMCAT_CSS_BIN}"
    
    if [ "${SETENVOVERRIDE_FILE_EXISTS}" -eq 1 ]
    then
        logPoint "Starting CSS server, may take a few minutes"
        ./StartCSS.sh >> "${LOG_FILE}" 2>&1
        # check for the startup message in the logs
        SERVER_STARTED=0
        while [ ${SERVER_STARTED} -eq 0 ]
        do
            sleep 5
            grep "Server startup in" "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_LOGS}"/css.0.log > /dev/null 2>>"${LOG_FILE}"
            if [ $? -eq 0 ]
            then
                SERVER_STARTED=1
            fi
        done
        logPoint "CSS server running"

        # display the url for users
        HOST_NAME=$(hostname -A | tr -s ' ' | cut -f1 -d' ')
        echo > tmphost.$$
        echo >> tmphost.$$
        if [ "${CSS_PORT}" -eq 443 ]
        then
            echo "   URL for CSS:  https://${HOST_NAME}/css " >> tmphost.$$
        elif [ "${CSS_PORT}" -eq 8443 ]
        then
            echo "   URL for CSS:  https://${HOST_NAME}:${CSS_PORT}/css " >> tmphost.$$
        elif [ "${CSS_PORT}" -eq 80 ]
        then
            echo "   URL for CSS:  http://${HOST_NAME}/css " >> tmphost.$$
        else
            echo "   URL for CSS:  http://${HOST_NAME}:${CSS_PORT}/css " >> tmphost.$$
        fi
        echo >> tmphost.$$

        # dump to the screen
        cat tmphost.$$

        # dump to the logs
        cat tmphost.$$ >> "${LOG_FILE}"

        rm -f tmphost.$$
    else
        logPoint "Not starting the server because the previous install didn't have a setenvoverride.sh script and it may need adjustments prior to starting."
        generateWarningErrorMessage 129 ${UPGRADE_BACKUP_TOMCAT_DIRECTORY}/${APACHE_TOMCAT_CSS_BIN} ${CSS_HOME}/${APACHE_TOMCAT_CSS_BIN}
        
    fi

    # go back to where you started
    cdOrFail "${CURRENT_PWD}"
}

# function: stopCSS
#
# parameters
#    none
#
# return
#    none
#
# function will stop the tomcat server, if running

function stopCSS
{

    if [ "${PREREQ_MODE}" -eq 0 ] && [ "${DOCKER_INSTALL}" -eq 0 ]
    then

        CURRENT_WAIT_TIME=0

        PID=$(ps -aef | grep java | grep "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_BIN}" | grep -v grep | tr -s ' ' | cut -f2 -d' ')
        variableNotEmpty "${PID}"
        if [ $? -eq 0 ]
        then
            if [ "${EXECUTION_STATE}" -eq "${UPGRADE_FROM_WLS}" ]
            then
                generateFatalErrorMessage 138 "${PID}" "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_BIN}"
            fi
            logPoint "Stopping CSS server"
            # stop the tomcat server
            CURRENT_PWD=$(pwd)
            if [ -d "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_BIN}" ]
            then
                cdOrFail "${CSS_HOME}"/"${APACHE_TOMCAT_CSS_BIN}"
                ./StopCSS.sh  >> "${LOG_FILE}" 2>>"${LOG_FILE}"
                # go back to where you started
                cdOrFail "${CURRENT_PWD}"

                # check for the startup message in the logs
                SERVER_STOPPED=0
                while [ ${SERVER_STOPPED} -eq 0 ]
                do
                    sleep "${STOP_WAIT_TIME}"

                    # keep track of loops waiting to for server to shutdown
                    CURRENT_WAIT_TIME=$(expr "${CURRENT_WAIT_TIME}" + "${STOP_WAIT_TIME}")

                    PID=$(ps -aef | grep java | grep "${CSS_HOME}" | grep -v grep | tr -s ' ' | cut -f2 -d' ')

                    if variableEmpty "${PID}"
                    then
                        SERVER_STOPPED=1
                    elif [ "${CURRENT_WAIT_TIME}" -ge "${MAX_TIME_TO_WAIT_FOR_STOP}" ]
                    then
                        # taking too long to shutdown, need to kill
                        kill -9 "${PID}" || generateFatalErrorMessage 147 "${PID}"
                        SERVER_STOPPED=1
                    fi
                done

                logPoint "CSS server stopped"
            fi
        fi
    fi
}
