#!/bin/bash
#
# Copyright (C) 2023 MOXA Inc. All rights reserved.
# This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
# See the file LICENSE for details.
#
# Authors:
#       2023  Wilson YS Huang  <wilsonys.huang@moxa.com>

# shellcheck disable=SC2317 # Don't warn about unreachable commands in this file

source "${INSTL_SCRIPT_DIR}/lib/util.sh"
source "${INSTL_SCRIPT_DIR}/lib/logger.sh"
log::init "${INSTL_LOG_FILE}" "${INSTL_LOG_LEVEL}"

set -e

process_file_uninstall() {
        local repo_name="$1"
        local repo_tag="$2"
        local repo_ver

        if util::is_exists "${INSTL_SRC_VERSION_FILE}" && grep -wq "${repo_name}" "${INSTL_SRC_VERSION_FILE}"; then
                repo_ver=$(grep -w "${repo_name}" "${INSTL_SRC_VERSION_FILE}" | awk -F ':' '{print $2}')
        else
                repo_ver="unknown"
        fi

        if util::confirm_prompt "Do you want to uninstall ${repo_name} (${repo_ver})?" "${INSTL_PROMPT_AUTO_YES}"; then
                source "${INSTL_SCRIPT_DIR}/uninstall.d/${repo_name}.uninstall.sh" "${repo_tag}" "${repo_ver}"

                sed -i "/$repo_name/d" "${INSTL_SRC_VERSION_FILE}"
                return 0
        else
                log::info "Skip uninstall ${repo_name}"
                return 1
        fi
}

process_config_uninstall() {
        local src_name="$1"
        local dst_path="$3"
        local remove_path

        if util::is_dir "${dst_path}"; then
                remove_path="${dst_path}${src_name}"
        else
                remove_path="${dst_path}"
        fi

        if util::confirm_prompt "Do you want to uninstall ${src_name} in ${dst_path}?" "${INSTL_PROMPT_AUTO_YES}"; then
                if util::is_exists "${remove_path}"; then
                        log::info "uninstall ${src_name}"
                        rm -f "${remove_path}"
                else
                        log::info "${src_name} was uninstalled, skip"
                fi
                return 0
        else
                log::info "Skip uninstall ${src_name}"
                return 1
        fi
}

process_package_compose() {
        local pkg_name="$1"
        local pkg_ver="$2"

        for pkg_file in "${INSTL_TOP_DIR}"/pkg/"${pkg_name}"/"${pkg_ver}"/*.deb; do
                binary_pkg_name=$(dpkg-deb --field "${pkg_file}" package)
                package_install="${package_install} ${binary_pkg_name}"
        done
}

process_package_uninstall() {
        if util::confirm_prompt "Do you want to uninstall packages? these packages will be uninstalled:${package_install}" "${INSTL_PROMPT_AUTO_YES}"; then
                log::info "uninstall packages:${package_install}"
                apt-get --purge -y remove "${package_install}" || true
                return 0
        else
                log::info "Skip install packages"
                return 1
        fi

        return 1
}

uninstall_debian_based_dev_tools() {
        apt-get remove build-essential linux-headers-"$(uname -r)" -y
}

uninstall_redhat_based_dev_tools() {
        yum groupremove "Development Tools" -y
        yum remove kernel-devel-"$(uname -r)" kernel-headers-"$(uname -r)" -y
}

main() {
        local drivers_list
        local tools_list
        local driver_available
        local tool_available
        local file_available
        local pkg_available

        driver_available=true
        tool_available=true
        file_available=true
        pkg_available=true

        export PATH=$PATH:/usr/sbin

        if util::is_exists "${INSTL_PRODUCT_DIR}/${BOARD_ID}/prerm.sh"; then
                log::info "=== Run pre-uninstall"
                source "${INSTL_PRODUCT_DIR}/${BOARD_ID}/prerm.sh"
        fi

        log::info "=== Uninstall driver"
        drivers_list="${INSTL_PRODUCT_DIR}/${BOARD_ID}/drivers"
        if ! util::parse_product_file "${drivers_list}" "${LINUX_KERNEL_MAJOR_VER}" "${LINUX_KERNEL_MINOR_VER}" process_file_uninstall; then
                driver_available=false
        fi

        log::info "=== Uninstall tool"
        tools_list="${INSTL_PRODUCT_DIR}/${BOARD_ID}/tools"
        if ! util::parse_product_file "${tools_list}" "${LINUX_KERNEL_MAJOR_VER}" "${LINUX_KERNEL_MINOR_VER}" process_file_uninstall; then
                tool_available=false
        fi

        if [ -n "${LINUX_DISTRO_VERSION_CODENAME}" ]; then
                codename="${LINUX_DISTRO_VERSION_CODENAME}"
        elif [ "${LINUX_DISTRO_ID}" = "rhel" ] || [ "${LINUX_DISTRO_ID}" = "rocky" ]; then
                codename="${LINUX_DISTRO_ID}_$(echo "${LINUX_DISTRO_VERSION}" | sed -n 's/.*(\(.*\)).*/\1/p')"
        else
                codename="${LINUX_DISTRO_ID}_${LINUX_DISTRO_VERSION_ID}"
        fi

        files_list="${INSTL_PRODUCT_DIR}/${BOARD_ID}/files"
        if util::is_exists "${files_list}"; then
                log::info "=== Uninstall file"
                if ! util::parse_product_file_from_codename "${files_list}" "${codename}" process_config_uninstall; then
                        file_available=false
                fi
        fi

        pkg_list="${INSTL_PRODUCT_DIR}/${BOARD_ID}/packages"
        if util::is_exists "${pkg_list}"; then
                log::info "=== Uninstall 3rd-party packages"
                if ! util::parse_product_file_from_codename "${pkg_list}" "${codename}" process_package_compose; then
                        pkg_available=false
                fi
                process_package_uninstall
        fi

        if [[ $driver_available = false ]] && [[ $tool_available = false ]] && [[ $file_available = false ]] && [[ $pkg_available = false ]]; then
                exit 3
        else
                if util::is_exists "${INSTL_PRODUCT_DIR}/${BOARD_ID}/postrm.sh"; then
                        log::info "=== Run post-uninstall"
                        source "${INSTL_PRODUCT_DIR}/${BOARD_ID}/postrm.sh"
                fi
                exit 0
        fi
}

main
