#!/bin/bash
#
# Startup script for Artifactory service
#
# chkconfig: 345 86 14
# description: Artifactory service
# processname: artifactory
# pidfile: /var/run/artifactory.pid
#
### BEGIN INIT INFO
# Provides:          artifactory
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start Artifactory on Tomcat
# Description:       Manages the services needed to run Artifactory on a dedicated Tomcat
### END INIT INFO
#

# service names inline with service route path
ARTIFACTORY_NAME=artifactory
METADATA_NAME=metadata
ACCESS_NAME=access
ROUTER_NAME=router
FRONTEND_NAME=frontend
EVENT_NAME=event
JFCONNECT_NAME=jfconnect
OBSERVABILITY_NAME=observability
TOPOLOGY_NAME=topology
ONEMODEL_NAME=onemodel

# Map contains environment variable key from old version (<7.x) to key from 7.x version
# This info will be used to assign value from old key to new key
# Note : Allowed values in a environment key are upper case alphabet, number and underscore 
ART_ENV_MAP="""
                ${ARTIFACTORY_NAME}.start.timeout=START_TMO
            """

errorArtHome() {
    echo
    echo -e "\033[31m** ERROR: $1\033[0m"
    echo
    exit 1
}

startTopology() {
    if runTopology; then
        chmod +x ${topologyScript}
        # TODO : Is this needed ?
        JAVA_OPTIONS="$JAVA_OPTIONS -Dartifactory.start.local.topology=true"
        su -m -s "/bin/sh" ${JF_ARTIFACTORY_USER} -c "${topologyScript} start"
    fi
}

stopTopology() {
    if runTopology; then
        chmod +x ${topologyScript}
        su -m -s "/bin/sh" ${JF_ARTIFACTORY_USER} -c "${topologyScript} stop"
    fi
}

addJfrogAccessBundledPropIfMissing() {
    if [ -f $TOMCAT_HOME/bin/setenv.sh ]; then
        grep "jfrog.access.bundled" $TOMCAT_HOME/bin/setenv.sh &> /dev/null
        if [ "$?" -gt 0 ]; then
            echo "" >> $TOMCAT_HOME/bin/setenv.sh
            echo 'export CATALINA_OPTS="$CATALINA_OPTS -Djfrog.access.bundled=true"' >> $TOMCAT_HOME/bin/setenv.sh
        fi
    fi
}

start() {
    # Start Tomcat in normal mode
    isAlive
    findShutdownPort
    if [ ${SHUTDOWN_PORT} -ne 0 ] || [ -n "$javaPs" ]; then
        logger "Artifactory Tomcat already started"
    else
        logger "Starting Artifactory tomcat as user $JF_ARTIFACTORY_USER..."
        rpmDebStartupActions

        # Remove old tomcat.pid in case exists
        rm -f ${CATALINA_PID}

        local startupCmd="export JAVA_HOME='$JAVA_HOME'; \
            source $JF_PRODUCT_HOME/app/bin/systemYamlHelper.sh; \
            source $JF_PRODUCT_HOME/app/bin/installerCommon.sh; \
            setupTomcatRedirection; \
            _createConsoleLog; \
            $TOMCAT_HOME/bin/startup.sh"
        
        for serviceScript in ${MANDATORY_JF_SERVICES_SCRIPT}; do
            performActionOnScriptAsUser "${serviceScript}" "start"
        done

        if $(isConsoleLogDisabled >/dev/null 2>&1); then
            su -s "/bin/bash" ${JF_ARTIFACTORY_USER} -c "${startupCmd}"
        else
            su -s "/bin/bash" ${JF_ARTIFACTORY_USER} -c "${startupCmd} >>${JF_PRODUCT_HOME}/var/log/console.log 2>&1"
        fi

        RETVAL=$?
        if [ ${RETVAL} -ne 0 ]; then
            errorArtHome "Artifactory Tomcat server did not start. Please check the logs"
        fi
        findShutdownPort
        nbSeconds=1

        getSystemValue "shared.script.serviceStartTimeout" "60"
        START_TMO="${YAML_VALUE}"

        while [ ${SHUTDOWN_PORT} -eq 0 ] && [ ${nbSeconds} -lt ${START_TMO} ]; do
            sleep 1
            let "nbSeconds = $nbSeconds + 1"
            findShutdownPort
        done
        if [ ${SHUTDOWN_PORT} -eq 0 ]; then
            # if artifactory does not come up within provided $START_TMO, stop tomcat
            su -s "/bin/sh" ${JF_ARTIFACTORY_USER} -c "export CATALINA_PID='${CATALINA_PID}'; \
                export JF_PRODUCT_HOME='${JF_PRODUCT_HOME}'; \
                export JAVA_HOME='${JAVA_HOME}'; $TOMCAT_HOME/bin/shutdown.sh" >/dev/null 2>&1
            errorArtHome "Artifactory Tomcat server did not start in $START_TMO seconds, tomcat will be stopped. This timeout can be modified by setting shared.script.serviceStartTimeout (default: 60) in ${JF_SYSTEM_YAML}. "
        fi
        logger "Artifactory Tomcat started in normal mode"

        createArtSvcPid
        startTopology

        [ $RETVAL=0 ] && touch $CATALINA_LOCK_FILE
    fi
}

stop() {
    isAlive
    findShutdownPort
    if [ ${SHUTDOWN_PORT} -eq 0 ] && [ -z "$javaPs" ]; then
        logger "Artifactory Tomcat already stopped"
        RETVAL=0
    else
        logger "Stopping Artifactory Tomcat..."
        if [ ${SHUTDOWN_PORT} -ne 0 ]; then
            su -s "/bin/sh" ${JF_ARTIFACTORY_USER} -c "export JAVA_HOME='$JAVA_HOME'; \
            $TOMCAT_HOME/bin/shutdown.sh"
            RETVAL=$?
        else
            RETVAL=1
        fi

        hardKillTomcat

        if [ ${SHUTDOWN_PORT} -eq 0 ] && [ -z "${javaPs}" ]; then
           logger "Artifactory Tomcat stopped"
        else
           logger "ERROR: Artifactory Tomcat did not stop"
           RETVAL=1
        fi
    fi

    for serviceScript in ${MANDATORY_JF_SERVICES_SCRIPT}; do
        performActionOnScriptAsUser "${serviceScript}" "stop"
    done

    stopTopology

    [ $RETVAL=0 ] && rm -f ${CATALINA_LOCK_FILE} ${JF_ARTIFACTORY_PID} ${CATALINA_PID}
}

start_and_wait() {
    local artLog=${JF_PRODUCT_HOME}/var/log/${ARTIFACTORY_NAME}/artifactory.log
    start
    if [ -e ${JF_ARTIFACTORY_PID} ]; then
        PID=$(cat ${JF_ARTIFACTORY_PID})
        while [ ! -e "${artLog}" ]; do
            sleep 10
        done

        tail -f ${artLog} &

        terminating() {
            logger "Received stop"
            stop
            while [ -e ${JF_ARTIFACTORY_PID} ] || [ ps ${PID} >/dev/null 2>&1 ]; do
                sleep 1
            done
            exit 0
        }
        trap terminating SIGINT SIGTERM

        while :; do
            sleep 5
        done
    fi
    logger "Something went wrong ${PID} $?"
}

status() {
    findShutdownPort
    if [ ${SHUTDOWN_PORT} -eq 0 ]; then
        if [ -e "$JF_ARTIFACTORY_PID" ]; then
            logger "ERROR: Artifactory is stopped but the pid file $JF_ARTIFACTORY_PID still exist"
            RETVAL=1
        else
            if [ -e "$CATALINA_LOCK_FILE" ]; then
                logger "ERROR: Artifactory is stopped but the lock file $CATALINA_LOCK_FILE still exist"
                RETVAL=2
            else
                logger "Artifactory Tomcat stopped"
                RETVAL=3
            fi
        fi
    else
        logger "Artifactory Tomcat running"
        RETVAL=0
    fi
}

sourceScript(){
    local fileName=$1

    [ ! -z "${fileName}" ] || errorExit "Target file is not set"
    [   -f "${fileName}" ] || errorExit "${fileName} file is not found"
    source "${fileName}"   || errorExit "Unable to source ${fileName}, please check if the $USER user has permissions to perform this action"
}

initHelpers(){
    local systemYamlHelper="${ARTIFACTORY_BIN_FOLDER}"/systemYamlHelper.sh
    local installerCommon="${ARTIFACTORY_BIN_FOLDER}"/installerCommon.sh
    local artCommon="${ARTIFACTORY_BIN_FOLDER}"/artifactoryCommon.sh

    export YQ_PATH="${ARTIFACTORY_BIN_FOLDER}/../third-party/yq"

    sourceScript "${systemYamlHelper}"
    sourceScript "${installerCommon}"
    sourceScript "${artCommon}"

    # init at each service startup 
    export JF_SYSTEM_YAML="${JF_PRODUCT_HOME}/var/etc/system.yaml"
    setupScriptLogsRedirection || true
}

init() {
    initHelpers
    translateEnv "${ART_ENV_MAP}"
    initJava
    initNode
}

check() {
    if [ -f ${JF_ARTIFACTORY_PID} ]; then
        echo "Artifactory is running with pid="$(cat ${JF_ARTIFACTORY_PID})
        echo ""
        exit 0
    fi

    echo "Checking arguments to Artifactory: "
    echo "JF_PRODUCT_HOME       =  ${JF_PRODUCT_HOME}"
    echo "JF_ARTIFACTORY_USER   =  ${JF_ARTIFACTORY_USER}"
    echo "TOMCAT_HOME           =  ${TOMCAT_HOME}"
    echo "JF_ARTIFACTORY_PID    =  ${JF_ARTIFACTORY_PID}"
    echo "JAVA_HOME             =  ${JAVA_HOME}"
    echo "JAVA_OPTIONS          =  ${JAVA_OPTIONS}"
    echo

    checkJavaVersion

    exit 1
}

JF_ARTIFACTORY_PID=""
# This will by changed by installservice to point to JF_PRODUCT_HOME/app/bin/artifactory.default, will have home and data information
artDefaultFile="__ARTIFACTORY_ENV_FILE__"

. ${artDefaultFile} || errorArtHome "ERROR: $artDefaultFile does not exist or not executable"

export JF_ARTIFACTORY_PID="/var/run/artifactory.pid"

ARTIFACTORY_BIN_FOLDER="${JF_PRODUCT_HOME}/app/bin"

MIN_MAX_OPEN_FILES=32000
MIN_MAX_OPEN_PROCESSES=1024

accessScript=${ARTIFACTORY_BIN_FOLDER}/../access/bin/access.sh
metadataScript=${ARTIFACTORY_BIN_FOLDER}/../metadata/bin/metadata.sh
onemodelScript=${ARTIFACTORY_BIN_FOLDER}/../onemodel/bin/onemodel.sh
routerScript=${ARTIFACTORY_BIN_FOLDER}/../router/bin/router.sh
frontendScript=${ARTIFACTORY_BIN_FOLDER}/../frontend/bin/frontend.sh
eventScript=${ARTIFACTORY_BIN_FOLDER}/../event/bin/event.sh
jfconnectScript=${ARTIFACTORY_BIN_FOLDER}/../jfconnect/bin/jfconnect.sh
observabilityScript=${ARTIFACTORY_BIN_FOLDER}/../observability/bin/observability.sh
topologyScript=${ARTIFACTORY_BIN_FOLDER}/../topology/bin/topology.sh

# Any new mandatory service to be started or stopped can be added to this variable
MANDATORY_JF_SERVICES_SCRIPT="${routerScript} ${metadataScript} ${frontendScript} ${observabilityScript}"

# Basic variables used
export CATALINA_PID_FOLDER=${JF_PRODUCT_HOME}/var/work/${ARTIFACTORY_NAME}/tomcat
export CATALINA_PID=${CATALINA_PID_FOLDER}/tomcat.pid
CATALINA_LOCK_FILE=${CATALINA_PID_FOLDER}/lock
CATALINA_MGNT_PORT=${CATALINA_MGNT_PORT:-8015}

init

if runOnemodel; then
    MANDATORY_JF_SERVICES_SCRIPT="${MANDATORY_JF_SERVICES_SCRIPT} ${onemodelScript}"
fi

if runAccess; then
    MANDATORY_JF_SERVICES_SCRIPT="${accessScript} ${MANDATORY_JF_SERVICES_SCRIPT}"
fi

if runJFConnect; then
  MANDATORY_JF_SERVICES_SCRIPT="${MANDATORY_JF_SERVICES_SCRIPT} ${jfconnectScript}"
fi

if runEvent; then
  MANDATORY_JF_SERVICES_SCRIPT="${MANDATORY_JF_SERVICES_SCRIPT} ${eventScript}"
fi

checkArtUser
checkArtHome
checkArData
checkTomcatHome

addJfrogAccessBundledPropIfMissing

RETVAL=0

case "$1" in
  start)
        checkJavaVersion
        start
        ;;
  wait)
        checkJavaVersion
        start_and_wait
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  redebug)
        stop
        ;;
  status)
        status
        ;;
  check)
        checkJavaVersion
        addExtraJavaArgs
        check
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|redebug|status|check}"
        exit 1
        ;;
esac

exit ${RETVAL}