#!/bin/bash

SERVICE_TYPE=""

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

checkRoot() {
    curUser=
    if [ -x "/usr/xpg4/bin/id" ]
    then
        curUser=$(/usr/xpg4/bin/id -nu)
    else
        curUser=$(id -nu)
    fi
    if [ "$curUser" != "root" ]
    then
        errorArtHome "Only root user can install artifactory as a service"
    fi

    if [ "$0" = "." ] || [ "$0" = "source" ]; then
        errorArtHome "Cannot execute script with source $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"
}

createArtUser() {
    echo -n "Creating user ${JF_ARTIFACTORY_USER}..."
    artifactoryUsername=$(getent passwd ${JF_ARTIFACTORY_USER} | awk -F: '{print $1}')
    if [ "$artifactoryUsername" = "${JF_ARTIFACTORY_USER}" ]; then
        echo -n "already exists..."
    else
        echo -n "creating..."
        useradd -r -d "${JF_PRODUCT_HOME}" -g "${JF_ARTIFACTORY_GROUP}" -M -s /usr/sbin/nologin ${JF_ARTIFACTORY_USER}
        if [ ! $? ]; then
            errorArtHome "Could not create user ${JF_ARTIFACTORY_USER}"
        fi
    fi
    echo " DONE"
}

saveUserGroupInfo(){
    setSystemValueNoOverride "shared.user" "${JF_ARTIFACTORY_USER}" "${JF_SYSTEM_YAML}" 2>/dev/null || true
    setSystemValueNoOverride "shared.group" "${JF_ARTIFACTORY_GROUP}" "${JF_SYSTEM_YAML}" 2>/dev/null || true
}

createArtGroup() {
    [ "${JF_ARTIFACTORY_GROUP}" == "" ] && return 0;
    echo -n "Creating Group ${JF_ARTIFACTORY_GROUP}..."
    artifactoryGroupname=$(getent group ${JF_ARTIFACTORY_GROUP} | awk -F: '{print $1}')
    if [ "$artifactoryGroupname" = "${JF_ARTIFACTORY_GROUP}" ]; then
        echo -n "already exists..."
    else
        echo -n "creating..."
        groupadd ${JF_ARTIFACTORY_GROUP}
        if [ ! $? ]; then
            errorArtHome "Could not create Group ${JF_ARTIFACTORY_GROUP}"
        fi
    fi
    echo " DONE"
}

createArtDefault() {
    echo -n "Modifying environment file $artDefaultFile..."

    sed --in-place -e "
        s,.*export JF_PRODUCT_HOME=.*,export JF_PRODUCT_HOME=${JF_PRODUCT_HOME},g;
        s,.*export JF_ARTIFACTORY_USER=.*,export JF_ARTIFACTORY_USER=${JF_ARTIFACTORY_USER},g;
        s,export TOMCAT_HOME=.*,export TOMCAT_HOME=${TOMCAT_HOME},g;" ${artDefaultFile} || \
            errorArtHome "Could not change values in $artDefaultFile"

    echo -e " DONE"
    echo -e "\033[33m** INFO: Please create/edit system.yaml file in $productEtcDir to set the correct environment\033[0m"
    echo -e "\033[33m         Templates with information can be found in the same directory\033[0m"
}

createArtRun() {
    # Since tomcat 6.0.24 the PID file cannot be created before running catalina.sh. Using /var/opt/jfrog/artifactory/run folder.
    if [ ! -d "$artRunDir" ]; then
        mkdir -p "$artRunDir" || errorArtHome "Could not create $artRunDir"
    fi
}

checkServiceStatus() {
    # Shutting down the artifactory service if running
    if [ -e "$artInitdFile" ]; then
        SERVICE_STATUS="$(${artInitdFile} status)"
        if [[ ! "$SERVICE_STATUS" =~ .*[sS]topped.* ]]; then
            echo "Stopping the artifactory service..."
            ${artInitdFile} stop || exit $?
        fi
    fi

    if [ -e "$artSystemdFile" ]; then
        SERVICE_STATUS="$(systemctl status artifactory.service)"
        if [[ ! "$SERVICE_STATUS" =~ .*[sS]topped.* ]]; then
            echo "Stopping the artifactory service..."
            systemctl stop artifactory.service || exit $?
        fi
    fi
}

installInitdService() {
    if [ -e ${artSystemdFile} ]; then
        rm -f ${artSystemdFile}
    fi
    if [ -e "$artInitdFile" ]; then
        cp -f ${artInitdFile} ${serviceFiles}/${serviceInitName}.disabled
    fi
    cp -f ${serviceFiles}/artifactory ${artInitdFile}
    chmod a+x ${artInitdFile}

    # Change default location if needed
    sed --in-place -e "
     /processname:/ s%artifactory%$serviceInitName%g;
     /Provides:/ s%artifactory%$serviceInitName%g;
     s%${envPlaceHolder}%${artDefaultFile}%g;
     " ${artInitdFile} || errorArtHome "Could not change values in $artInitdFile"

    # Try update-rc.d for debian/ubuntu else use chkconfig
    if [ -x /usr/sbin/update-rc.d ]; then
        echo
        echo -n "Initializing artifactory service with update-rc.d..."
        update-rc.d ${serviceInitName} defaults && \
        chkconfigOK=true
    elif [ -x /usr/sbin/chkconfig ] || [ -x /sbin/chkconfig ]; then
        echo
        echo -n "Initializing $serviceInitName service with chkconfig..."
        chkconfig --add ${serviceInitName} && \
        chkconfig ${serviceInitName} on && \
        chkconfig --list ${serviceInitName} && \
        chkconfigOK=true
    else
        ln -s ${artInitdFile} /etc/rc3.d/S99${serviceInitName} && \
        chkconfigOK=true
    fi
    [ ${chkconfigOK} ] || errorArtHome "Could not install artifactory service"
    echo -e " DONE"
    SERVICE_TYPE="init.d"
}

installSystemdService() {
    if [ -e ${artInitdFile} ]; then
        mv ${artInitdFile} ${artInitdFile}.disabled
    fi
    serviceFiles=${ARTIFACTORY_BIN_FOLDER}/../misc/service
    if [ -e "${artSystemdFile}" ]; then
        mv ${artSystemdFile} ${serviceFiles}/${serviceSystemdName}.disabled
    fi
    cp -f ${serviceFiles}/artifactory.service ${artSystemdFile}
    chmod a+x ${artSystemdFile}

    # Edit artifactory.service for artifactoryManage.sh script location
    sed -i "s|ExecStart=\/opt\/jfrog\/artifactory\/app\/bin\/artifactoryManage.sh start|ExecStart=${ARTIFACTORY_BIN_FOLDER}\/artifactoryManage.sh start|g; \
    s|ExecStop=\/opt\/jfrog\/artifactory\/app\/bin\/artifactoryManage.sh stop|ExecStop=${ARTIFACTORY_BIN_FOLDER}\/artifactoryManage.sh stop|g;" ${artSystemdFile}

    # Use the systemctl command to enable the service
    echo -n "Initializing $serviceSystemdName service with systemctl..."
    systemctl daemon-reload &>/dev/null
    systemctl enable artifactory &>/dev/null
    systemctl list-unit-files --type=service | grep artifactory.service &>/dev/null || errorArtHome "Could not install artifactory service"
    echo -e " DONE"
    SERVICE_TYPE="systemd"
}

installService() {
    checkServiceStatus
    # Distribution-specific logic
    systemctl -h > /dev/null 2>&1
    if [[ $? -eq 0 ]]; then
        # Installing service from type systemd
        installSystemdService
    else
        # Installing service from type init.d
        installInitdService
    fi
}

copyTomcatEnv() {
    cp ${serviceFiles}/setenv.sh ${TOMCAT_HOME}/bin/setenv.sh && \
    chmod a+x ${TOMCAT_HOME}/bin/* || errorArtHome "Could not set the $TOMCAT_HOME/bin/setenv.sh"
}

setPermissions() {
    echo
    echo "Setting file permissions..."
    chown -RL ${JF_ARTIFACTORY_USER}:${JF_ARTIFACTORY_GROUP} ${JF_PRODUCT_HOME}/app || errorArtHome "Could not set permissions"
    checkAndSetOwnerOnDir "${JF_PRODUCT_HOME}/var" "${JF_ARTIFACTORY_USER}" "${JF_ARTIFACTORY_GROUP}"
}

showSummary() {
    echo
    echo -e "\033[33m************ SUCCESS ****************\033[0m"
    echo -e "\033[33mInstallation of Artifactory completed\033[0m"
    echo
    echo "Note: We recommend that you use Artifactory with an external PostgreSQL database."
    echo "      For details about how to configure the database, refer to"
    echo "      https://jfrog.com/help/r/jfrog-installation-setup-documentation/postgresql-for-artifactory"
    echo
    echo "      To run Artifactory with any database other than PostgreSQL (embedded Derby,"
    echo "      MySQL, Oracle, Microsoft SQL Server and MariaDB),before running Artifactory," 
    echo "      you are required to set the allowNonPostgresql parameter as true."
    echo
    echo "      For more information, refer to"
    echo "      https://jfrog.com/help/r/jfrog-installation-setup-documentation/choose-the-right-database"
    echo

    if [ ${SERVICE_TYPE} == "init.d" ]; then
        echo "Start Artifactory with:"
        echo "> service artifactory start (or $artInitdFile start)"
        echo
        echo "Check Artifactory status with:"
        echo "> service artifactory status (or $artInitdFile status)"
    fi

    if [ ${SERVICE_TYPE} == "systemd" ]; then
        echo "Start Artifactory with:"
        echo "> systemctl start artifactory.service"
        echo
        echo "Check Artifactory status with:"
        echo "> systemctl status artifactory.service"
    fi
    echo
    echo "Logs can be found under ${JF_PRODUCT_HOME}/var/log"
    echo "System configuration templates can be found under ${JF_PRODUCT_HOME}/var/etc"
    echo "Copy any configuration you want to modify from the template to ${JF_PRODUCT_HOME}/var/etc/system.yaml"
    echo
}

##
checkRoot

ARTIFACTORY_BIN_FOLDER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
artExtractDir="$(cd "$(dirname "$ARTIFACTORY_BIN_FOLDER")" && pwd)"
serviceFiles=${ARTIFACTORY_BIN_FOLDER}/../misc/service

envPlaceHolder=__ARTIFACTORY_ENV_FILE__

mkdir -p ${artExtractDir}/../var || errorArtHome "Could not create dir ${artExtractDir}/../var"

[ -n "$JF_PRODUCT_HOME" ] || JF_PRODUCT_HOME="$(cd "$(dirname "$ARTIFACTORY_BIN_FOLDER")"/.. && pwd)"
[ -n "$productEtcDir" ]   || productEtcDir="${JF_PRODUCT_HOME}/var/etc"

export JF_PRODUCT_HOME

export CATALINA_PID_FOLDER=${JF_PRODUCT_HOME}/var/work/artifactory/tomcat
export CATALINA_PID=${CATALINA_PID_FOLDER}/tomcat.pid

TOMCAT_HOME="${JF_PRODUCT_HOME}/app/artifactory/tomcat"
artLogDir="${JF_PRODUCT_HOME}/var/log/artifactory"
artRunDir="${JF_PRODUCT_HOME}/app/run"

[ -n "$artInitdFile" ] || artInitdFile="/etc/init.d/artifactory"

if [ -z "$artSystemdFile" ]; then
    SUSE=$(cat /etc/issue | grep -io suse)
    NOSUSE=$(echo $SUSE | tr "[:upper:]" "[:lower:]")
    UNAME=$(uname | tr "[:upper:]" "[:lower:]")
    if [ "$UNAME" == "linux" ] && [ "$NOSUSE" != "suse" ]; then
        artSystemdFile="/lib/systemd/system/artifactory.service"
    else
        artSystemdFile="/usr/lib/systemd/system/artifactory.service"
    fi
fi

serviceInitName=$(basename ${artInitdFile})
serviceSystemdName=$(basename ${artSystemdFile})

artDefaultFile="${ARTIFACTORY_BIN_FOLDER}/artifactory.default"

initHelpers
syncEtc

# This will set JF_ARTIFACTORY_USER and JF_ARTIFACTORY_GROUP (default artifactory:artifactory)
setUserGroup "$1" "$2"

echo
echo "Installing artifactory as a Unix service that will run as user ${JF_ARTIFACTORY_USER}${JF_ARTIFACTORY_GROUP:+ and group $JF_ARTIFACTORY_GROUP}"
echo "Installing artifactory with home ${JF_PRODUCT_HOME}/app"

createArtGroup

createArtUser

createArtDefault

createArtRun

installService

copyTomcatEnv

prepareTomcat

setPermissions

saveUserGroupInfo

showSummary
