#!/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/apk/repositories.d/alt-ruby-els.list"

ALT_COMMON_PACKAGE_URI="https://repo.alt.tuxcare.com/alt-common/alt-common-release-install.apk"
ELS_RUBY_PACKAGE_URI="https://repo.alt.tuxcare.com/alt-ruby-els/els-ruby-release-install.apk"

# Temporary files
ALT_COMMON_TEMP_APK=""
ELS_RUBY_TEMP_APK=""

exec 3>&1

cleanup() {
    if [[ -f "$ELS_RUBY_TEMP_APK" ]]; then
        rm -f "$ELS_RUBY_TEMP_APK"
    fi

    if [[ -f "$ALT_COMMON_TEMP_APK" ]]; then
        rm -f "$ALT_COMMON_TEMP_APK"
    fi

    exec 3>&-
}

trap cleanup EXIT

log() {
    printf "%s\\n" "$1" 1>&3
}

show_usage() {
    echo 'Usage: install-els-alt-ruby-apk-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 '  -h, --help          Show this message and exit'
}

do_opts() {
    if [ $# -eq 0 ]; then
        log "$(show_usage)"
        exit 1
    fi
    while [ $# -gt 0 ]; do
        key="$1"
        case $key in
            -h|--help)
                log "$(show_usage)"
                exit 0
                ;;
            -l|--license-key)
                if [[ -z "$2" || "$2" == -* ]]; then
                    log "Error: --license-key requires an argument"
                    log "$(show_usage)"
                    exit 1
                fi
                LICENSE="$2"
                shift
                ;;
            -f|--force)
                FORCE=true
                ;;
            -d|--delete)
                DELETE=true
                ;;
            -*|--*)
                log "Unknown option: $key"
                log "$(show_usage)"
                exit 1
                ;;
        esac
        shift
    done

    if [ -z "$LICENSE" ] && [ "$DELETE" != "true" ]; then
        log "Required argument not provided: --license-key"
        log "$(show_usage)"
        exit 1
    fi
}

alt_ruby_els_installed() {
    log "Checking if els-ruby-release is already installed... "
    if apk info -e els-ruby-release >/dev/null 2>&1; then
        log "els-ruby-release package is already installed."
        return 0
    fi
    log "els-ruby-release package is not installed"
    return 1
}

extract_token() {
    if [ ! -f "$AUTH_CONF_PATH" ]; then
        log "ERROR: Auth config file not found at $AUTH_CONF_PATH"
        return 1
    fi

    token=$(sed -n 's|.*/alt-ruby-els/\([^/]*\)/apk/.*|\1|p' "$AUTH_CONF_PATH")

    if [[ -z "$token" || "$token" != *SERVER* ]]; then
        log "ERROR: Invalid token in $AUTH_CONF_PATH (empty or missing SERVER marker)"
        return 1
    fi

    echo "$token"
    return 0
}

unregister_token() {
    if ! token=$(extract_token); then
        return 1
    fi

    log "Unregistering server token..."

    response=$(curl -i -s -X POST "${CLN_UNREGISTER_SERVER}?token=${token}")
    curl_exit_code=$?

    if [ $curl_exit_code -ne 0 ]; then
        log "ERROR: Failed to connect to unregister server (curl exited with status: $curl_exit_code)"
        return 1
    fi

    if ! echo "$response" | grep -qi '^HTTP/[0-9.]*[[:space:]]200'; then
        if [[ -z "$response" ]]; then
            log "elstoken wasn't found. Server is not registered"
        else
            log "Got incorrect status from CLN: $response"
        fi
        return 1
    fi

    log "Unregistered successfully"
    return 0
}

remove_alt_ruby_els() {
    log "Removing els-ruby-release package... "
    if apk del els-ruby-release 1>&3; then
        log "Removed els-ruby-release package successfully"
    else
        log "Error: Could not remove els-ruby-release package"
        return 1
    fi

    log "Alt ruby ELS deleted successfully"
    return 0
}

delete_alt_ruby_els() {
    if alt_ruby_els_installed; then
        if [ "$FORCE" = "true" ]; then
            unregister_token || log "Warning: Failed to unregister, but continuing with force delete"
            remove_alt_ruby_els
        else
            if ! unregister_token; then
                log "Couldn't deactivate account"
                return 12
            fi
            remove_alt_ruby_els
        fi
    else
        log "ELS is not installed"
    fi
    log "ELS Alt Ruby removal completed"
    return 0
}

get_auth_token() {
    log "Request repository token for this server... "
    local data="{\"key\": \"$3\", \"host_name\": \"$2\"}"
    local ret
    ret=$(curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d "$data" "$1")
    if [ $? -ne 0 ]; then
        log "Error (Curl command failed)"
        return 1
    fi
    local token
    token=$(echo "$ret" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
    if [ -n "$token" ]; then
        log "Ok"
        echo "$token"
        return 0
    fi
    log "Error (No token was returned from CLN)"
    return 1
}

install_alt_common_release() {
    log "Checking if alt-common-release is already installed... "
    if apk info -e alt-common-release >/dev/null 2>&1; then
        log "alt-common-release package is already installed."
        return 0
    fi
    log "Installing alt-common-release..."

    ALT_COMMON_TEMP_APK=$(mktemp /tmp/alt-common-releaseXXXXXX)
    mv "$ALT_COMMON_TEMP_APK" "$ALT_COMMON_TEMP_APK.apk"
    ALT_COMMON_TEMP_APK="$ALT_COMMON_TEMP_APK.apk"

    if ! curl -fsSL -o "$ALT_COMMON_TEMP_APK" "$ALT_COMMON_PACKAGE_URI"; then
        log "Error: Couldn't download alt-common-release.apk"
        return 1
    fi

    if ! apk add "$ALT_COMMON_TEMP_APK" --allow-untrusted; then
        log "Error: Couldn't install alt-common-release"
        return 3
    fi

    log "alt-common-release installed successfully"
    return 0
}

install_els_ruby_release() {
    if ! install_alt_common_release; then
        return 2
    fi
    log "Installing els-ruby-release..."

    ELS_RUBY_TEMP_APK=$(mktemp /tmp/els-ruby-release-XXXXXX)
    mv "$ELS_RUBY_TEMP_APK" "$ELS_RUBY_TEMP_APK.apk"
    ELS_RUBY_TEMP_APK="$ELS_RUBY_TEMP_APK.apk"

    if ! curl -fsSL -o "$ELS_RUBY_TEMP_APK" "$ELS_RUBY_PACKAGE_URI"; then
        log "Error: Couldn't download els-ruby-release.apk"
        return 1
    fi

    if ! apk add "$ELS_RUBY_TEMP_APK" --allow-untrusted; then
        log "Error: Couldn't install els-ruby-release"
        return 3
    fi

    log "els-ruby-release installed successfully"
    return 0
}

validate_supported_os() {
    if [[ -f /etc/alpine-release ]]; then
        local version
        version=$(cat /etc/alpine-release)
        log "Detected Alpine Linux system, version $version"

        if [[ $version == 3.22* ]]; then
            log "Alpine version 3.22 is supported"
            return 0
        else
            log "Unsupported Alpine version: $version (requires 3.22)"
            return 1
        fi
    fi

    log "Not an Alpine Linux system"
    return 1
}

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

main() {
    do_opts "$@"

    if ! check_superuser_privileges; then
        return 14
    fi

    if ! validate_supported_os; then
        log "Unsupported OS detected"
        return 1
    fi

    if [ "$DELETE" = "true" ];  then
        delete_alt_ruby_els
        return $?
    fi

    if alt_ruby_els_installed; then
        if [ "$FORCE" = "true" ]; then
            unregister_token
            remove_alt_ruby_els
        else
            log "This server has installed ELS repo and token"
            log "For re-registration license run script with --force"
            return 2
        fi
    fi

    log "Registering in CLN..."
    local token
    token=$(get_auth_token "$CLN_REGISTER_SERVER" "$HOSTNAME" "$LICENSE")
    if [ $? -ne 0 ]; then
        return 3
    fi

    log "Applying repository token for this server..."
    if ! install_els_ruby_release; then
        return 9
    fi

    if ! sed -i "s/\$TOKEN/$token/g" "$AUTH_CONF_PATH"; then
        log "Error (Could not write to $AUTH_CONF_PATH)"
        return 10
    fi

    log "ELS for alt ruby installed successfully"
}

main "$@"
