#!/bin/bash

# TODO - address which directory the install script is run from
export PATH="${PATH}:/bin:/sbin:/usr/bin:/usr/sbin"

readonly AEMBIT_USER_NAME="aembit"
INSTALLER_DIR="$(dirname ${0})"

check_for_required_env_var() {
    env_var_name=$1
    env_var_value="${!env_var_name}"

    if [ -z "${env_var_value}" ]; then
        echo "Required environment variable \"${env_var_name}\" is not defined."
        exit 1
    fi
} 

check_if_package_missing() {
    package=$1

    if ! which "${package}" > /dev/null 2>&1; then
        if [ -z "${missing_packages}" ]; then
            missing_packages="${package}"
        else
            missing_packages="${missing_packages}, ${package}"
        fi
    fi
}

check_required_dependencies() {
    echo "Checking for required package dependencies."

    check_if_package_missing ps
    check_if_package_missing grep
    check_if_package_missing id
    check_if_package_missing useradd
    check_if_package_missing curl
    check_if_package_missing update-ca-certificates

    if [ -n "${missing_packages}" ]; then
        echo "One or more necessary packages were missing. Please install the following package(s) and then rerun the installer: ${missing_packages}" 
        exit 1
    fi
}

check_for_existing_installation() {
    # TODO - upgrade behavior should be opt-in.
    if ps axco command | grep --quiet "aembit_agent_proxy"; then
        echo "An existing Aembit installation was found. Please uninstall."
        exit 1
    fi

    if [ -d "/opt/aembit/edge/agent_proxy" ] && [ $(ls -1 /opt/aembit/edge/agent_proxy | wc -l) -ne 0 ]; then 
        echo "An existing Aembit installation was found. Please uninstall."
        exit 1
    fi

}

create_user() {
    if id "${AEMBIT_USER_NAME}" > /dev/null 2>&1; then
        echo "User \"${AEMBIT_USER_NAME}\" exists"
    else
        echo "User \"${AEMBIT_USER_NAME}\" does not exist. Creating."
        if useradd --no-create-home --shell /usr/bin/nologin "${AEMBIT_USER_NAME}"; then
            echo "User created"
        else
            echo "There was an error creating the \"${AEMBIT_USER_NAME}\" user."
            exit 1
        fi
    fi
}

set_up_logs() {
    if ! cp $INSTALLER_DIR/installer_components/journald@aembit_agent_proxy.conf /etc/systemd/journald@aembit_agent_proxy.conf; then
        echo "Unable to copy the journald configuration file to host."
        exit 1
    fi
}

generate_tenant_root_cert_url() {
    echo "https://${TENANT_ID}.${BASE_DOMAIN}/api/tenant/download-root-ca"
}

install_tenant_root_cert() {
    if ! curl "$(generate_tenant_root_cert_url)" --output /usr/local/share/ca-certificates/aembit.crt; then
        echo "Unable to get the Aembit tenant's root certificate."
        exit 1
    fi
    if ! update-ca-certificates; then
        echo "Unable to update the host's trusted CA certificates."
        exit 1
    fi
}

copy_static_components_to_host() {
    if ! mkdir --parents /opt/aembit/edge/agent_proxy/1.9.1257/bin/; then
        echo "Unable to make installation directory for Agent Proxy binary."
        exit 1
    fi

    if ! cp $INSTALLER_DIR/aembit_agent_proxy /opt/aembit/edge/agent_proxy/1.9.1257/bin/aembit_agent_proxy; then
        echo "Unable to move the Agent Proxy binary to the installation directory."
        exit 1
    fi
    
    if ! mkdir --parents /opt/aembit/edge/agent_proxy/1.9.1257/scripts/; then
        echo "Unable to make installation directory for Agent Proxy scripts."
        exit 1
    fi

    if ! cp $INSTALLER_DIR/installer_components/iptables_up.sh /opt/aembit/edge/agent_proxy/1.9.1257/scripts/iptables_up.sh; then
        echo "Unable to move the iptables startup script to the installation directory."
        exit 1
    fi

    if ! cp $INSTALLER_DIR/installer_components/iptables_down.sh /opt/aembit/edge/agent_proxy/1.9.1257/scripts/iptables_down.sh; then
        echo "Unable to move the iptables shutdown script to the installation directory."
        exit 1
    fi
    
    if ! cp $INSTALLER_DIR/uninstall /opt/aembit/edge/agent_proxy/1.9.1257/scripts/uninstall; then
        echo "Unable to move the Agent Proxy uninstall script to the installation directory."
        exit 1
    fi
} 

install_systemd_service() {
    if ! cp $INSTALLER_DIR/installer_components/aembit_agent_proxy.service /etc/systemd/system/aembit_agent_proxy.service; then
        echo "Unable to copy the systemd service file to the destination."
        exit 1
    fi

    if ! sed --in-place "s#{{ AGENT_CONTROLLER_LOCATION }}#${AEMBIT_AGENT_CONTROLLER}#" /etc/systemd/system/aembit_agent_proxy.service; then
        echo "Unable to update the Agent Controller location in the systemd service file."
        exit 1
    fi

    if ! systemctl enable aembit_agent_proxy.service; then
        echo "Unable to enable the Agent Proxy systemd service."
        exit 1
    fi

    if ! systemctl start aembit_agent_proxy.service; then
        echo "Unable to start the Agent Proxy systemd service."
        exit 1
    fi
}

run_installer() {
    if [ "$(id --user)" -ne 0 ]; then
        echo "Installer must be run as root."
        exit 1
    fi

    check_for_required_env_var AEMBIT_AGENT_CONTROLLER || exit 1
    check_for_required_env_var TENANT_ID || exit 1
    check_for_required_env_var BASE_DOMAIN || exit 1

    check_required_dependencies || exit 1
    check_for_existing_installation || exit 1
    create_user || exit 1
    set_up_logs || exit 1
    install_tenant_root_cert || exit 1
    copy_static_components_to_host || exit 1 
    install_systemd_service || exit 1
}

main() {
    set -o pipefail
    run_installer 2>&1 | tee installer.log
}

main || exit 1
