#!/usr/bin/env bash
#
#               __
#              /\ \__
#   __    _____\ \ ,_\ _____     __      ___
# /'__`\ /\ '__`\ \ \//\ '__`\ /'__`\   /'___\
#/\ \L\.\\ \ \L\ \ \ \\ \ \L\ /\ \L\.\_/\ \__/
#\ \__/.\_\ \ ,__/\ \__\ \ ,__\ \__/.\_\ \____\
# \/__/\/_/\ \ \/  \/__/\ \ \/ \/__/\/_/\/____/
#           \ \_\        \ \_\
#            \/_/         \/_/
# a pacman wrapper with syntax based on debian's apt
# (c) 2019-2020 Fascode Network.
# License: Do What The Fuck You Want To Public License
# maintained by Yamada Hayao

# Enter the path to the AUR helper you want to use here. 
# If it is empty, the corresponding AUR helper will be searched automatically.
#AURHELPER=


set -e
APTPAC_VERSION="3.3.0"
PACMAN_OPTIONS=()
HELPERS=(
    "/usr/bin/yay"
    "/usr/bin/paru"
    "/usr/bin/yaourt"
    "/usr/bin/aurman"
    "/usr/bin/pikaur"
    "/usr/bin/pacaur"
    "/usr/bin/aura"
    "/usr/bin/wfa"
)
DEFAULT_PACMAN_COMMAND="/usr/bin/pacman"
PACMAN_COMMAND="${DEFAULT_PACMAN_COMMAND}"
PACMAN_CONFIG="/etc/pacman.conf"
DEBUG=false
RUN_WITH_SUDO=false

direct_option=false
autoremove=false

_msg_error () {
    echo -e "${@}" >&2
}

_msg_debug () {
    if "${DEBUG}"; then
        echo -e "${@}" >&1
    fi
}

if [[ ! "${UID}" = 0 ]]; then
    if [[ -z "${AURHELPER+SET}" ]]; then
        for AURHELPER in "${HELPERS[@]}"; do
            if [[ -f "${AURHELPER}" ]]; then
                PACMAN_COMMAND="${AURHELPER}"
                break
            elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then
                PACMAN_COMMAND="$(basename "${AURHELPER}")"
                break
            fi
        done
    else
        if [[ -f "${AURHELPER}" ]]; then
            PACMAN_COMMAND="${AURHELPER}"
        elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then
            PACMAN_COMMAND="$(basename "${AURHELPER}")"
        else
            _msg_error "${AURHELPER} is not installed"
            exit 1
        fi
    fi
fi


# List option
installed=false

_usage () {
    echo "usage ${0} [options] [command] [packages]"
    echo
    echo " apt commands:"
    echo "    install                              Install the specified package"
    echo "    remove                               Remove the specified package"
    echo "    purge                                Permanently remove the package"
    echo "    update                               Update package database"
    echo "    upgrade | full-upgrade               Update packages"
    echo "    edit-sources                         Edit config file of pacman"
    echo "    search                               Search for a package"
    echo "    autoremove                           Remove unnecessary packages"
    echo "    clean                                Remove the package cache"
    echo "    list                                 Display a list of packages"
    echo "    show | showpkg                       Display the package records"
    echo "    rdepends                             Display the dependencies"
    echo
    echo " apt options:"
    echo "    -y | --yes  | --assume-yes           Do not check"
    echo "    -d | --download-only                 Only download the package"
    echo "    -c | --config-file <file>            Config file for pacman"
    echo "    -h | --help                          Display this help"
    echo "    -v | --version                       Display the version of aptpac and pacman"
    echo "         --auto-remove | --autoremove    Remove unnecessary packages with other command"
    echo "         --purge                         Delete the entire configuration file"
    echo
    echo " pacapt options:"
    echo "         --aur-helper <command>          Specifies the command to use as the AUR helper"
    echo "                                         Ignored if pacapt is run as root"
    echo "                                         Specify AUR helper that supports common command line options with pacman"
    echo
    echo " aptpac supports not only above options but also options of pacman"
}

_exit () {
    exit "${1}"
}

_version () {
cat << EOF
aptpac ${APTPAC_VERSION} - A pacman wrapper with syntax based on debian's apt
License: Do What The Fuck You Want To Public License
(c) 2019-2020 Fascode Network. Yamada Hayao
EOF
echo
pacman --version
}


ADD_OPTION () {
    PACMAN_OPTIONS+=("${@}")
}

# Argument analysis and processing
set +e
PACAPT_ARGUMENTS=("${@}")
_opt_short="ydfc:hvVDFQRSTU"
_opt_long="yes,assume-yes,download-only,fix-broken,purse,installed,debug,help,version,config-file:,auto-remove,autoremove,aur-helper:"
OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- "${@}" 2> /dev/null)
set -e
#if [[ ${?} != 0 ]]; then
#    exit 1
#fi

eval set -- "${OPT}"
#echo "Argument is \"${OPT}\""
unset OPT _opt_short _opt_long

while true; do
    case "${1}" in
        -y | --yes | --assume-yes)
            ADD_OPTION "--noconfirm"
            shift 1
            ;;
        -d | --download-only)
            ADD_OPTION "-w"
            shift 1
            ;;
        -f | --fix-broken)
            shift 1
            ;;
        -c | --config-file)
            PACMAN_CONFIG="${2}"
            shift 2
            ;;
        --purge)
            ADD_OPTION "-n"
            shift 1
            ;;
        --installed)
            installed=true
            shift 1
            ;;
        --debug)
            DEBUG=true
            shift 1
            ;;
        -h | --help)
            _usage
            shift 1
            exit 0
            ;;
        -v | --version)
            _version
            shift 1
            exit 0
            ;;
        --autoremove | --auto-remove)
            autoremove=true
            shift 1
            ;;
        --aur-helper)
            if [[ ! "${UID}" = 0 ]] && [[ -f "${2}" ]]; then
                PACMAN_COMMAND="${2}"
            elif [[ "${UID}" = 0 ]]; then
                _msg_warn "The specified AUR helper is not used because pacapt is running on the root."
            elif hash "$(basename "${2}")" 2> /dev/null; then
                PACMAN_COMMAND="$(basename "${2}")"
            else
                _msg_error "${2} is not installed"
                exit 1
            fi
            shift 2
            ;;
        -V | -D | -F | -Q | -R | -S | -T | -U)
            direct_option=true
            ADD_OPTION "${PACAPT_ARGUMENTS[@]}"
            break
            ;;
        --)
            shift 1
            break
            ;;
        *)
            _msg_error "Invalid argument '${1}'"
            _help
            exit 1
            ;;
    esac
done

if [[ "${direct_option}" = false ]]; then
    if [[ $# -lt 1 ]]; then
        _msg_error "No command specified"
        _usage
        _exit 1
    fi
    COMMAND="${1}"

    shift 1

    PACKAGE=("${@}")

    case "${COMMAND}" in
        install)
            ADD_OPTION "-S"
            ;;
        remove)
            ADD_OPTION "-Rsc"
            ;;
        purge)
            ADD_OPTION "-Rsnc"
            ;;
        update)
            ADD_OPTION "-Syy"
            ;;
        upgrade)
            ADD_OPTION "-Syu"
            ;;
        search)
            ADD_OPTION "-Ss"
            ;;
        full-upgrade)
            ADD_OPTION "-Syu"
            ;;
        clean)
            ADD_OPTION "-Sccc"
            ;;
        dist-upgrade)
            ADD_OPTION "-Syu"
            ;;
        edit-sources)
            if [[ -n "${EDITOR}" ]]; then
                sudo "${EDITOR}" "${PACMAN_CONFIG}"
            else
                sudo nano "${PACMAN_CONFIG}"
            fi
            _exit 0
            ;;
        huawei) 
            if [[ "$(source "/etc/locale.conf" 2> /dev/null; echo -n "${LANG}")" = "ja_JP.UTF-8" ]]; then
                echo "(ง •ᴗ•)ว ⁾⁾ﾌｧｰｳｪｲでｳｪｲｳｪｲ"
                _exit 0
            else
                _msg_error "Invalid command '${COMMAND}'"
                _exit 1
            fi
            ;;
        moo)
            echo "         (__) "
            echo "         (oo) "
            echo "   /------\/ "
            echo "  / |    ||   "
            echo " *  /\---/\ "
            echo "    ~~   ~~   "
            echo "...."Have you mooed today?"..."
            exit 0
            ;;
        autoremove) 
            if [[ -n "$(${PACMAN_COMMAND} -Qttdq)" ]]; then
                ADD_OPTION "-Rsc"
                while read -r pkg; do
                    PACKAGE+=("${pkg}")
                done < <(${PACMAN_COMMAND} -Qttdq)
            else
                echo "No packages to remove"
                exit 0
            fi
            ;;
        list)
            if ${installed}; then
                ADD_OPTION "-Q | grep"
            else
                ADD_OPTION "-Ss"
            fi
            ;;
        show | showpkg)
            for pkg in "${PACKAGE[@]}"; do
                if pacman -Qq "${pkg}" 2> /dev/null 1>&2; then
                    ${PACMAN_COMMAND} "${PACMAN_OPTIONS[@]}" -Qi --config "${PACMAN_CONFIG}" "${pkg}"
                else
                    ${PACMAN_COMMAND} "${PACMAN_OPTIONS[@]}" -Si --config "${PACMAN_CONFIG}" "${pkg}"
                fi
            done
            unset pkg
            _exit 0
            ;;
        rdepends)
            ADD_OPTION "-Sii"
            ;;
        *)
            _msg_error "Invalid command '${COMMAND}'"
            _exit 1
            ;;
    esac
fi

if [[ ! "${PACMAN_COMMAND}" = "${DEFAULT_PACMAN_COMMAND}" ]] && [[ ! "$(basename "${PACMAN_COMMAND}")" = "$(basename "${DEFAULT_PACMAN_COMMAND}")" ]]; then
    _msg_debug "Use AUR helper ${PACMAN_COMMAND}"
else
    RUN_WITH_SUDO=true
fi

_sudo(){
    if "${RUN_WITH_SUDO}"; then
        eval sudo "${@}"
    else
        eval "${@}"
    fi
}

_sudo "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" --config "${PACMAN_CONFIG}" "${PACKAGE[@]}"

if "${autoremove}"; then
    if [[ -n $(${PACMAN_COMMAND} -Qttdq) ]]; then
        "${PACMAN_COMMAND}" -Qttdq | _sudo "${PACMAN_COMMAND}" -Rsc --config "${PACMAN_CONFIG}" -
    else
        echo "No packages to remove"
        exit 0
    fi
fi
