#!/usr/bin/env bash

CLN_REGISTER_SERVER="https://cln.cloudlinux.com/cln/api/els/server/register"
CLN_UNREGISTER_SERVER="https://cln.cloudlinux.com/cln/api/els/server/unregister"
LICENSE=""
HOSTNAME=`hostname`
AUTH_CONF_PATH="/etc/yum/vars/elstoken"
PACKAGE_URI="https://repo.tuxcare.com/centos7-els/els-os-release-install.el7.x86_64.rpm"

show_usage() {
    echo 'Usage: install-centos7-els-repo.sh [OPTION]...'
    echo ''
    echo '  -l, --license-key   User license key'
    echo '  -f, --force         Force re-register if ELS is already installed'
    echo '  -d, --delete        Delete ELS from server'
    echo '  -v, --validate      Check if ELS is installed'
    echo '  -h, --help          Show this message and exit'
}

els_installed() {
    echo "Checking if ELS is already installed... "

    # Check for new installation method (els-os-release package)
    if yum list installed els-os-release 2>/dev/null; then
        echo "els-os-release package is already installed."
        return 0
    fi

    # Check for old installation method (elstoken file and repo files)
    if [[ -f "$AUTH_CONF_PATH" || -f /etc/yum.repos.d/centos7-els.repo ]]; then
        echo "ELS is installed using the old installation method."
        return 0
    fi

    return 1
}

install_els_os_release() {
    TEMP_RPM=$(mktemp /tmp/els-os-release-XXXXXX.rpm)

    trap 'rm -f "$TEMP_RPM"' EXIT

    if ! curl -fsSL -o "$TEMP_RPM" "$PACKAGE_URI"; then
        echo "Error: Couldn't download els-os-release.rpm"
        exit 1
    fi

    if ! yum install -y "$TEMP_RPM"; then
        echo "Error: Couldn't install els-os-release"
        exit 3
    fi
}

remove_els_installation() {
    # Remove new installation method (els-os-release package)
    if yum list installed els-os-release 2>/dev/null; then
        echo "Removing els-os-release package... "
        if yum remove -y els-os-release; then
            echo "Ok"
        else
            echo "Error (Could not remove els-os-release package)"
            exit 1
        fi
    fi

    # Remove old installation method files
    echo "Removing authentication configuration file... "
    if rm -f "$AUTH_CONF_PATH"; then
        echo "Ok"
    else
        echo "Error (Could not remove auth configuration file: $AUTH_CONF_PATH)"
        exit 1
    fi

    echo "Removing old repository configuration files... "
    if ! rm -f /etc/yum.repos.d/centos7-els.repo; then
        echo "Error (Could not remove centos7-els.repo)"
        exit 1
    fi

    if ! rm -f /etc/yum.repos.d/centos7-els-rollout.repo; then
        echo "Error (Could not remove centos7-els-rollout.repo)"
        exit 1
    fi
}

check_rpm_version() {
    local package="$1"
    local required_version="$2"

    if ! rpm -q "$package" &>/dev/null; then
        echo "ERROR: $package is not installed"
        return 1
    fi

    local current_version=$(rpm -q --qf '%{VERSION}-%{RELEASE}' "$package")
    local comparison=$(rpm --eval "%{lua: print(rpm.vercmp('$current_version', '$required_version'))}")

    if [ "$comparison" -ge 0 ]; then
        return 0
    else
        return 1
    fi
}

check_eol_repos() {
    echo "Checking if server repositories are updated for post-EOL usage..."

    if ! check_rpm_version "nss-softokn" "3.90.0-1"; then
        echo "Error: Your system has an outdated version of 'nss-softokn'."
        echo "Required version: 3.90.0-1 or newer."
        echo ""
        echo "Please update the package by running:"
        echo "  yum update nss-softokn"
        echo ""
        echo "If you are unable to update, it is likely due to outdated or unreachable repositories."
        echo ""
        echo "To switch to supported vault repositories, run the following commands:"
        echo "  sed -i 's|mirror.centos.org|vault.centos.org|g' /etc/yum.repos.d/*.repo"
        echo "  sed -i 's|mirrorlist.centos.org|vault.centos.org|g' /etc/yum.repos.d/*.repo"
        echo "  sed -i 's|#baseurl=|baseurl=|g' /etc/yum.repos.d/*.repo"
        echo "  sed -i 's|mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/*.repo"
        echo ""
        echo "Then clean and rebuild the yum cache:"
        echo "  yum clean all && yum makecache"
        echo ""
        echo "After updating your repositories, try updating the package again:"
        echo "  yum update nss-softokn"
        echo ""
        echo "For detailed help, visit:"
        echo "   https://support.tuxcare.com/hc/en-us/articles/17220332955036"
        return 1
    fi

    echo "Repository accessibility check passed"
    return 0
}

if [[ $# -eq 0 ]]; then
    echo "An option should be specified. See usage -h, --help."
    exit 1
fi


check_superuser_privileges() {
    echo "Checking for superuser privileges..."
    if [ "$(id -u)" -ne 0 ]; then
        echo "Error: This script must be run with superuser privileges"
        return 1
    fi
    echo "Superuser privileges confirmed"
    return 0
}

for opt in "$@"; do
    case ${opt} in
        -l|--license-key)
            if [[ -z "$2" || "$2" == -* ]]; then
                echo "Error: --license-key requires an argument"
                show_usage
                exit 1
            fi
            LICENSE=$2 ; shift ;;
        -f|--force)
            FORCE=true ; shift ;;
        -d|--delete)
            DELETE=true ; shift ;;
        -v|--validate)
            VALIDATE=true ; shift ;;
        -h|--help)
            show_usage ; exit 0 ;;
        -*|--*)
            echo; echo "Unrecognized option: ${opt}"; show_usage ; exit 1 ;;
    esac
done

if ! check_superuser_privileges; then
    exit 14
fi

if [[ -n $VALIDATE ]]; then
    if els_installed; then
        if [[ -f "$AUTH_CONF_PATH" ]]; then
            TOKEN=$(cat "$AUTH_CONF_PATH")
            if [[ -n "$TOKEN" ]]; then
                echo "Server is registered with token $TOKEN"
            else
                echo "Server is registered but token file is empty"
            fi
        else
            echo "Server is registered but token file not found"
        fi
        exit 0
    else
        echo "Server is not registered"
        exit 1
    fi
fi

if [[ -n $FORCE ]]; then
    if ! remove_els_installation; then
        exit 1
    fi
fi

if [[ -n $DELETE ]]; then
    # Attempt to unregister from server (if token exists)
    UNREGISTERED=false
    if [[ -f "$AUTH_CONF_PATH" ]]; then
        TOKEN=$(cat "$AUTH_CONF_PATH")
        echo "Attempting to unregister server..."
        CLN_UNREGISTER=$(curl -i -s -X POST "$CLN_UNREGISTER_SERVER?token=$TOKEN")
        if [[ "$CLN_UNREGISTER" == *"200"* ]]; then
            echo "Server unregistered successfully"
            UNREGISTERED=true
        else
            echo "Warning: Failed to unregister server: $CLN_UNREGISTER"
        fi
    else
        echo "No token file found - server may not be registered"
    fi

    # Remove ELS installation regardless of unregistration status
    echo "Removing ELS installation..."
    if ! remove_els_installation; then
        exit 1
    fi

    if [[ "$UNREGISTERED" == true ]]; then
        echo "CentOS ELS deleted successfully"
    else
        echo "CentOS ELS removed successfully (server was not registered)"
    fi
    exit
fi

# check centos-release file
if [[ ! -f /etc/centos-release ]]; then
    echo "This server is not RHEL based"
    exit 1
fi

# check centos version
centos_release="$(cat /etc/centos-release)"
if [[ ! "${centos_release}" == *"CentOS Linux release 7.9"* ]]; then
    echo "This server is not CentOS Linux release 7.9"
    exit 1
fi

if ! check_eol_repos; then 
    exit 1
fi

# check license key
if [[ -z $LICENSE ]]; then
    echo "License key should be specified with -l, --license-key."
    echo "See -h, --help."
    exit 1
fi

# check if els is installed
if els_installed; then
    echo "This server has already installed ELS repo and token"
    echo "For re-registration license run script with --force"
    exit 1
fi

# get token
CLN_REGISTER=$(curl -i -X POST -H "Content-Type: application/json" -H "accept: */*" -d "{\"key\": \"$LICENSE\", \"host_name\": \"$HOSTNAME\"}" "$CLN_REGISTER_SERVER")
CLN_CODE=$(head -n1 <<< "$CLN_REGISTER")

if [[ ! "$CLN_CODE" == *"200"* ]]; then
    echo "Got incorrect status from CLN: $CLN_REGISTER"
    exit 1
fi

TOKEN=$(echo "$CLN_REGISTER" | grep -oP '"token":"\K[\w\d-]*')

if [[ -z $TOKEN ]]; then
    echo "Something went wrong. Token is not defined"
    exit 1
fi

if ! echo "${TOKEN}" > "$AUTH_CONF_PATH"; then
    echo "Error: Could not write to $AUTH_CONF_PATH"
    exit 10
fi

if ! install_els_os_release; then
    exit 14
fi

yum clean all
if ! yum install -y els-define --disablerepo=* --enablerepo=centos7-els; then
    echo "Error: Couldn't install els-define"
    exit 1
fi

echo "CentOS 7 ELS installed successfully"

