#!/bin/sh
PRODUCT_INFO=appmanager
PACKAGE_NAME=AppManagerDataExporter

SCRIPT_DIR="$(dirname "$0")"
ENV_FILE="service.env"

. "${SCRIPT_DIR}/${ENV_FILE}"

CheckFlags() {
for arg in "$@"; do
    
    if [ "$arg" = $QUIET ]; then
      PRINT_OUTPUT=$QUIET
    fi
    
    if [ "$arg" = $ROOT_USER ]; then
      USER_TYPE=$ROOT_USER
    fi
    
    if [ "$arg" = $NOT_ROOT_USER ]; then
      USER_TYPE=$NOT_ROOT_USER
    fi

    if [ "$arg" = $AS_SERVICE ]; then
      SERVICE_REGISTRATION=$AS_SERVICE
    fi

    if [ "$arg" = $NOT_AS_SERVICE ]; then
      SERVICE_REGISTRATION=$NOT_AS_SERVICE
    fi
done
}

PrintToTerminal() {
    if [ $PRINT_OUTPUT = $NOT_QUIET ]; then
        echo "$@"
    fi
}

ModifyServiceScript() {
    PrintToTerminal "Action: Modifying service script"
    
    if [ $USER_TYPE = $ROOT_USER ]; then
        # Modify .sh script
        sed -i -e "/.*USER_TYPE=.*/{s/.*USER_TYPE=.*/USER_TYPE=\"${ROOT_USER}\"/}" "${SCRIPT_DIR}/service.env"
        # Modify .service script
        sed -i 's/^\(User=\)/#&/' "${SCRIPT_DIR}/${PACKAGE_NAME}.service"
    else
        # Modify .sh script
        sed -i -e "/.*USER_TYPE=.*/{s/.*USER_TYPE=.*/USER_TYPE=\"${NOT_ROOT_USER}\"/}" "${SCRIPT_DIR}/service.env"
        # Modify .service script
        sed -i 's/^\(#User=\)/User=/' "${SCRIPT_DIR}/${PACKAGE_NAME}.service"
    fi
    
    if [ $SERVICE_REGISTRATION = $NOT_AS_SERVICE ]; then
        # Modify .sh script
        sed -i -e "/.*SERVICE_REGISTRATION=.*/{s/.*SERVICE_REGISTRATION=.*/SERVICE_REGISTRATION=\"${NOT_AS_SERVICE}\"/}" "${SCRIPT_DIR}/service.env"
    else
        # Modify .sh script
        sed -i -e "/.*SERVICE_REGISTRATION=.*/{s/.*SERVICE_REGISTRATION=.*/SERVICE_REGISTRATION=\"${AS_SERVICE}\"/}" "${SCRIPT_DIR}/service.env"
    fi

    PrintToTerminal "Info: Modified service script"
}

CreateUser() {
	useradd "${PRODUCT_INFO}-user" || PrintToTerminal "Info: User already exists."
}

GrantPermission() {
	chmod 777 "${SCRIPT_DIR}/../../${PACKAGE_NAME}" -R
    chown "${PRODUCT_INFO}-user" "${SCRIPT_DIR}/../../${PACKAGE_NAME}" -R
}

CheckServiceType() {
	PrintToTerminal "Action: Checking service type"

    which systemctl >> /dev/null
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        PrintToTerminal "Info: systemctl available"
        IS_SYSTEMCTL=$BOOLEAN_TRUE
    fi

    which update-rc.d >> /dev/null
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        PrintToTerminal "Info: init.d available"
        IS_INITD=$BOOLEAN_TRUE
    fi
}

RegisterAsSystemctlService() {
    PrintToTerminal "Action: Registering as systemctl service"
	  
    cp "${SCRIPT_DIR}/${PACKAGE_NAME}.service" "/etc/systemd/system/${PACKAGE_NAME}.service"
	systemctl enable "${PACKAGE_NAME}.service"
	systemctl daemon-reload

    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        PrintToTerminal "Info: Registered as systemctl service"
    else
        PrintToTerminal "Info: Failed to register as systemctl service"
    fi
}

DeregisterAsSystemctlService() {
    PrintToTerminal "Action: Deregistering as systemctl service"

	systemctl disable "${PACKAGE_NAME}.service"
	systemctl daemon-reload
	rm /etc/systemd/system/"${PACKAGE_NAME}.service"

    PrintToTerminal "Info: Deregistered as systemctl service"
}

RegisterAsInitdService() {
    PrintToTerminal "Action: Registering as init.d service"
	  
    cp "${SCRIPT_DIR}/${PACKAGE_NAME}.sh" "/etc/init.d/${PACKAGE_NAME}"
    chmod +x "/etc/init.d/${PACKAGE_NAME}"
    update-rc.d ${PACKAGE_NAME} defaults

    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        PrintToTerminal "Info: Registered as init.d service"
    else
        PrintToTerminal "Info: Failed to register as init.d service"
    fi
}

DeregisterAsInitdService() {
    PrintToTerminal "Action: Deregistering as init.d service"
	  
    update-rc.d -f ${PACKAGE_NAME} remove
	rm "/etc/init.d/${PACKAGE_NAME}"

    PrintToTerminal "Info: Deregistered as init.d service"
}

RegisterAsService() {

    PrintToTerminal "Action: Registering as service"
    
    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        RegisterAsSystemctlService
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        RegisterAsInitdService
    else
        PrintToTerminal "Info: Cannot register as service"
    fi
}

DeregisterAsService() {

    PrintToTerminal "Action: Deregistering as service"
    
    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        DeregisterAsSystemctlService
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        DeregisterAsInitdService
    else
        PrintToTerminal "Info: Not registered as service"
    fi
}

SetGlobals() {
	PrintToTerminal "Action: Setting Globals"

    SERVICE_NAME="${PACKAGE_NAME}Service"
    UPDATER_NAME="${PACKAGE_NAME}Updater"
    INSTALLER_NAME="${PACKAGE_NAME}Installer"

    if [ $SERVICE_REGISTRATION = $AS_SERVICE ]; then
        CheckServiceType
    fi
}

version() {
    cat "${SCRIPT_DIR}/version"
}

update() {
    PrintToTerminal "Action: Updating $SERVICE_NAME"
    
    stop
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        cp "${SCRIPT_DIR}/${UPDATER_NAME}" "${SCRIPT_DIR}/../${UPDATER_NAME}"
        PrintToTerminal "Action: Update started"
        GrantPermission
        su "${PRODUCT_INFO}-user" -c "${SCRIPT_DIR}/../${UPDATER_NAME}" 
        PrintToTerminal "Action: Update completed"
        start
        return 0
    else 
        return $cmdstatus
    fi
}

install() {
   PrintToTerminal "Action: Installing $SERVICE_NAME"

    ModifyServiceScript

    if [ "$USER_TYPE" = $NOT_ROOT_USER ]; then
        CreateUser
    fi

    RegisterAsService

    stop
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        if [ "$USER_TYPE" = $NOT_ROOT_USER ]; then
            GrantPermission
            su "${PRODUCT_INFO}-user" -c "${SCRIPT_DIR}/${INSTALLER_NAME} $*"
        else
            "${SCRIPT_DIR}/${INSTALLER_NAME}" "$@"
        fi
        start
        return $?        
    else
        PrintToTerminal "Info: Installation failed, Unable to stop ${SERVICE_NAME}"
        return $cmdstatus
    fi
}

configure() {
   PrintToTerminal "Action: Configuring $SERVICE_NAME"

    stop
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        su "${PRODUCT_INFO}-user" -c "${SCRIPT_DIR}/${INSTALLER_NAME} $*"
        start
        return $?        
    else
        PrintToTerminal "Info: Configuring failed, Unable to stop ${SERVICE_NAME}"
        return $cmdstatus
    fi
}

uninstall() {
    PrintToTerminal "Action: Uninstalling $SERVICE_NAME"

    stop
    cmdstatus=$?
    if [ "$cmdstatus" -eq 0 ]; then
        DeregisterAsService
        "${SCRIPT_DIR}/${INSTALLER_NAME}" "$@" &
    else
        PrintToTerminal "Info: Uninstallation failed, Unable to stop ${SERVICE_NAME}"
    fi
}

health() {
    while :
    do
        status
        cmdstatus=$?
        if [ "$cmdstatus" -eq 0 ]; then
            PIDS=$(pgrep -f "$SERVICE_NAME")
            for ID in $PIDS
            do
                PrintToTerminal "Info: $SERVICE_NAME PID($ID)"
            done
            sleep 15
        else
            PrintToTerminal "Status: $SERVICE_NAME is in stopped state"
            exit 1
        fi
    done
}

service_start() {
    service_status
    cmdstatus=$?
    if [ $cmdstatus -ne 0 ]; then
        "${SCRIPT_DIR}/${SERVICE_NAME}" &
        sleep 5
    fi
}

start() {
    PrintToTerminal "Action: Starting $SERVICE_NAME"

    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        systemctl start "${PACKAGE_NAME}.service"
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        /etc/init.d/${PACKAGE_NAME} start
    else
        if [ $USER_TYPE = $NOT_ROOT_USER ]; then
            su "${PRODUCT_INFO}-user" -c "${SCRIPT_DIR}/service.sh service_start -q"
        else
            service_start
        fi
    fi

    service_status
    cmdstatus=$?
    if [ $cmdstatus -eq 0 ]; then
        PrintToTerminal "Info: $SERVICE_NAME started successfully"
        return $cmdstatus
    else
        PrintToTerminal "Info: Unable to start $SERVICE_NAME"
        return $cmdstatus
    fi
}

service_stop() {
    PIDS=$(pgrep -f "$SERVICE_NAME")
    for ID in $PIDS
    do
        kill "$ID"
        cmdstatus=$?
        if [ "$cmdstatus" -eq 0 ]; then
            PrintToTerminal "Info: $SERVICE_NAME ($ID) stopped"
        else
            PrintToTerminal "Info: Cannot stop $SERVICE_NAME ($ID)"
        fi
    done

    sleep 5 

}

stop() {
    PrintToTerminal "Action: Stopping $SERVICE_NAME"

    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        systemctl stop "${PACKAGE_NAME}.service"
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        /etc/init.d/${PACKAGE_NAME} stop
    else
        if [ $USER_TYPE = $NOT_ROOT_USER ]; then
            su "${PRODUCT_INFO}-user" -c "${SCRIPT_DIR}/service.sh service_stop -q"
        else
            service_stop
        fi
    fi

    service_status
    cmdstatus=$?
    if [ $cmdstatus -eq 0 ]; then
        PrintToTerminal "Info: Unable to stop $SERVICE_NAME"
        return 1
    else
        PrintToTerminal "Info: $SERVICE_NAME stopped successfully"
        return 0
    fi
}

service_restart() {

    stop
    
    start
    
}

restart() {
    PrintToTerminal "Action: Restarting $SERVICE_NAME"

    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        systemctl restart "${PACKAGE_NAME}.service"
        return $?
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        /etc/init.d/${PACKAGE_NAME} restart
        return $?
    else
        service_restart
    fi
}

service_status() {
    if pgrep -f "$SERVICE_NAME" > /dev/null; then
        PrintToTerminal "Status: $SERVICE_NAME is in running state"
        return 0
    else
        PrintToTerminal "Status: $SERVICE_NAME is in stopped state"
        return 1
    fi
}

status() {
    PrintToTerminal "Action: Checking $SERVICE_NAME status"
    if [ "$IS_SYSTEMCTL" = "$BOOLEAN_TRUE" ]; then 
        systemctl status "${PACKAGE_NAME}.service"
        return $?
    elif [ "$IS_INITD" = "$BOOLEAN_TRUE" ]; then 
        /etc/init.d/${PACKAGE_NAME} status
        return $?
    else
        service_status
        return $?
    fi
}

run() {
    install "install" "$@"
    health
}

check_user() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "Error: This script must be executed with sudo or as root."
        exit 1
    fi
}

#script starts here

CheckFlags "$@"

SetGlobals

case "${1}" in 
    start)
        check_user
        start
        ;;
    stop)
        check_user
        stop
        ;;
    restart)
        check_user
        restart
        ;;
    status)
        check_user
        status
        ;;
    update)
        check_user
        update
        ;;    
    health)
        check_user
        health
        ;;  
    install)
        check_user
        install "$@"
        ;;  
    run)
        check_user
        run "$@"
        ;;
    configure)
        check_user
        configure "$@"
        ;;  
    uninstall)
        check_user
        uninstall "$@"
        ;;
    service_start)
        service_start
        ;;
    service_stop)
        service_stop
        ;;
    service_restart)
        service_restart
        ;;
    service_status)
        service_status
        ;;    
    version)
        version
        ;;    
    *)
    PrintToTerminal "Operation [${1}] not supported"
    exit 1
    ;;
esac



