#!/bin/sh
#
# Perform necessary datadog-agent setup steps before package is installed.
#
# .deb: STEP 2 of 5
# .rpm: STEP 2 of 6

INSTALL_DIR=/opt/datadog-agent
LOG_DIR=/var/log/datadog
SERVICE_NAME=datadog-agent

KNOWN_DISTRIBUTION="(Debian|Ubuntu|RedHat|CentOS|openSUSE|Amazon|Arista|SUSE)"
DISTRIBUTION=$(lsb_release -d 2>/dev/null | grep -Eo $KNOWN_DISTRIBUTION  || grep -Eo $KNOWN_DISTRIBUTION /etc/issue 2>/dev/null || grep -Eo $KNOWN_DISTRIBUTION /etc/Eos-release 2>/dev/null || grep -m1 -Eo $KNOWN_DISTRIBUTION /etc/os-release 2>/dev/null || uname -s)
if [ -f "/etc/debian_version" ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
    DISTRIBUTION_FAMILY="Debian"
fi
# Linux installation
if [ "$DISTRIBUTION" != "Darwin" ]; then
    set -e

    if [ -f "/lib/systemd/system/$SERVICE_NAME.service" ] || [ -f "/usr/lib/systemd/system/$SERVICE_NAME.service" ]; then
        # Stop an already running agent
        # Only supports systemd and upstart
        if command -v systemctl >/dev/null 2>&1; then
            systemctl stop $SERVICE_NAME-process || true
            systemctl stop $SERVICE_NAME-sysprobe || true
            systemctl stop $SERVICE_NAME-trace || true
            systemctl stop $SERVICE_NAME-security || true
            systemctl stop $SERVICE_NAME || true
        elif command -v initctl >/dev/null 2>&1; then
            initctl stop $SERVICE_NAME-process || true
            initctl stop $SERVICE_NAME-sysprobe || true
            initctl stop $SERVICE_NAME-trace || true
            initctl stop $SERVICE_NAME-security || true
            initctl stop $SERVICE_NAME || true
        elif [ "$DISTRIBUTION_FAMILY" = "Debian" ]; then
            if command -v service >/dev/null 2>&1; then
                service $SERVICE_NAME-process stop || true
                service $SERVICE_NAME-sysprobe stop || true
                service $SERVICE_NAME-trace stop || true
                service $SERVICE_NAME-security stop || true
                service $SERVICE_NAME stop || true
            else
                echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd, upstart and sysvinit."
            fi
        else
            echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd and upstart."
        fi
    fi

    # For versions < 6.10 using the custom datadog-pip, TUF and in-toto files were kept in TUF_REPO_DIR.
    # They were not being cleaned by these versions, so let's do that now on install/upgrade
    TUF_REPO_DIR=$INSTALL_DIR/repositories
    if [ -d $TUF_REPO_DIR ]; then
        rm -rf $TUF_REPO_DIR
    fi

    if [ -f "/etc/debian_version" ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
        # Nothing specific on Debian
        :
        #DEBHELPER#
    elif [ -f "/etc/redhat-release" ] || [ -f "/etc/system-release" ] || [ -f "/etc/SuSE-release" ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "openSUSE" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "Arista" ]; then
        # RPM Agents < 5.18.0 expect the preinst script of the _new_ package to stop the agent service on upgrade (which is defined with an init.d script on Agent 5)
        # So let's stop the Agent 5 service here until we don't want to support upgrades from Agents < 5.18.0 anymore
        if [ -f "/etc/init.d/datadog-agent" ]; then
            /etc/init.d/datadog-agent stop || true
        fi

        # Set up `dd-agent` user and group
        getent group dd-agent >/dev/null || groupadd -r dd-agent
        getent passwd dd-agent >/dev/null || \
            useradd -r -M -g dd-agent -d $INSTALL_DIR -s /sbin/nologin \
                -c "Datadog Agent" dd-agent && \
                { usermod -L dd-agent || echo "[ WARNING ]\tCannot lock the 'dd-agent' user account"; }


        # Starting with 6.10, integrations are also uninstalled on package removal

        # Since 6.18.0, a file containing all integrations files which have been installed by
        # the package is available. We use it to remove only the datadog-related check files which
        # have *NOT* been installed by the package (eg: installed using the `integration` command).

        if [ -f "$INSTALL_DIR/embedded/.installed_by_pkg.txt" ]; then
            echo "Removing integrations installed with the 'agent integration' command"

            # List all files in the embedded dir of the datadog-agent install dir
            PREV_DIR=$(pwd)
            cd $INSTALL_DIR
            find . -depth -path './embedded/lib/python*/site-packages/datadog_*' > $INSTALL_DIR/embedded/.all-integrations.txt

            # List all files in the embedded dir of the datadog-agent install dir
            # which were not installed by the package and rm them.
            grep -Fxv -f $INSTALL_DIR/embedded/.installed_by_pkg.txt $INSTALL_DIR/embedded/.all-integrations.txt | grep -v '^#' | xargs --no-run-if-empty -I '{}' rm -r $INSTALL_DIR/{}

            rm $INSTALL_DIR/embedded/.all-integrations.txt
            cd "$PREV_DIR"
        else
            PIP2_PATH=$INSTALL_DIR/embedded/bin/pip2
            PIP3_PATH=$INSTALL_DIR/embedded/bin/pip3
            if [ -x $PIP2_PATH ]; then
                echo "Uninstalling Python 2 integrations..."
                $PIP2_PATH freeze | grep ^datadog- | grep -v datadog-checks-base | xargs $PIP2_PATH uninstall -y -q --no-cache-dir || true
            fi
            if [ -x $PIP3_PATH ]; then
                echo "Uninstalling Python 3 integrations..."
                $PIP3_PATH freeze | grep ^datadog- | grep -v datadog-checks-base | xargs $PIP3_PATH uninstall -y -q --no-cache-dir || true
            fi
        fi

        # Delete all the .pyc/.pyo files in the embedded dir that are part of the old agent's package
        # This MUST be done after using pip or any python, because executing python might generate .pyc files
        if [ -f "$INSTALL_DIR/embedded/.py_compiled_files.txt" ]; then
            # (commented lines are filtered out)
            cat $INSTALL_DIR/embedded/.py_compiled_files.txt | grep -v '^#' | xargs rm -f
        fi

    else
        echo "[ FAILED ]\tYour system is currently not supported by this script.";
        exit 1;
    fi
else
    # macOS
    mkdir -p $LOG_DIR

    CONF_DIR="$INSTALL_DIR/etc"
    APP_DIR="/Applications/Datadog Agent.app"

    LOG_FILE="$LOG_DIR/preinstall.log"
    exec > $LOG_FILE 2>&1

    # Determine current user if he is using the Graphical installer
    # shellcheck disable=SC2009
    INSTALL_USER=$(ps aux | grep "CoreServices/Installer" | grep -v grep | awk '{print $1;}')

    # Otherwise, we hope he is using the install script and try to use this user
    # If it fails, no choice but to use root :'(
    if [ -z "$INSTALL_USER" ] || [ "$INSTALL_USER" = "root" ]; then
        INSTALL_USER=$(cat /tmp/datadog-install-user || echo 'root')
    fi
    echo "INSTALL_USER: $INSTALL_USER"

    USER_HOME=$(sudo -Hu "$INSTALL_USER" sh -c 'echo $HOME')

    if [ -e "$CONF_DIR/datadog.conf" ] || [ -e "$CONF_DIR/datadog.yaml" ]; then
        echo "# State at the beginning"
        echo "## Agent version"
        grep AGENT_VERSION $INSTALL_DIR/agent/config.py || echo "No config.py file (agent 5)"
        datadog-agent version || echo "No datadog-agent binary version (agent 6)"
        echo "## $INSTALL_DIR"
        ls -al $INSTALL_DIR || echo "No agent installed"
        echo "## $APP_DIR/Contents/Resources"
        ls -al "$APP_DIR/Contents/Resources" || echo "No app installed"

        echo '# Stop old agent'
        echo '## Trying to stop agent 5'
        $INSTALL_DIR/bin/datadog-agent stop || true
        echo '## Trying to stop agent 6'
        sudo -Hu "$INSTALL_USER" launchctl stop com.datadoghq.agent || true
        echo '## Trying to kill agent GUI'
        kill "$(pgrep -f 'Datadog Agent.app')"

        echo '## Trying to unload agent 6 launchd service'
        sudo -Hu "$INSTALL_USER" launchctl unload -w "$USER_HOME/Library/LaunchAgents/com.datadoghq.agent.plist" || true

        # Save old conf
        rm -rvf /tmp/{checks,conf}.d/* /tmp/datadog.conf /tmp/datadog.yaml
        mkdir -vp /tmp/{conf,checks}.d
        cp -vf $CONF_DIR/datadog.conf /tmp
        cp -vf $CONF_DIR/datadog.yaml /tmp
        cp -vfR $CONF_DIR/conf.d/* /tmp/conf.d
        find /tmp/conf.d '(' -name '*.yaml.example' -o -name '*.yaml.default' ')' -delete -print # don't save old example and default yamls
        cp -vfR $CONF_DIR/checks.d/* /tmp/checks.d
    fi

    echo '# Deleting old datadog-agent link'
    rm -vf /usr/local/bin/datadog-agent

    echo '# Deleting old datadog-agent files'
    rm -rf $INSTALL_DIR/agent || true
    rm -rf $INSTALL_DIR/checks.d || true

    echo "# Disabling the login launch of the app"
    sudo -u "$INSTALL_USER" osascript -e 'tell application "System Events" to delete every login item whose name is "Datadog Agent"'

    # Debriefing time
    echo "# State at the end"
    echo "## Agent version"
    grep AGENT_VERSION $INSTALL_DIR/agent/config.py || echo "No config.py file (agent 5)"
    datadog-agent version || echo "No datadog-agent binary version (agent 6)"
    echo "## $INSTALL_DIR"
    ls -al $INSTALL_DIR || echo "No agent installed"
    echo "## $APP_DIR/Contents/Resources"
    ls -al "$APP_DIR/Contents/Resources" || echo "No app installed"
fi

exit 0
