#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
# MPM (Meta Package Manager)
#
# Copyright (C) 2024-2026 Arnaud G. GIBERT
# mailto:arnaud@rx3.net
#
# This is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; If not, see
# <https://www.gnu.org/licenses/>.
#
#-----------------------------------------------------------------------------------------------------------------------------------



#-----------------------------------------------------------------------------------------------------------------------------------
# Includes
#-----------------------------------------------------------------------------------------------------------------------------------

: "${RX3_LIB_DIR:=/usr/lib/rx3}"
. "${RX3_LIB_DIR}/base.bash"





#-----------------------------------------------------------------------------------------------------------------------------------
# Global Variables
#-----------------------------------------------------------------------------------------------------------------------------------

declare -g  VERSION="1.1.2"
declare -g     NAME="mpm"
declare -g     HELP="usage: [-h | --help] | [-V | --version] | [-l | --list] | [-i | --install <mpm_name>] [-T | --test] [-v | --verbose] [-r | --repo <repository_url>]"

declare -g     MODE="DEFAULT"
declare -g  VERBOSE="FALSE"
declare -g  DRY_RUN="FALSE"
declare -g   RETVAL=0

declare -g MPM_REPO="https://www.rx3.net/mpm-repository"
declare -g MPM_NAME=""

if [[ -f /etc/mpm.conf ]]
then
    . /etc/mpm.conf
fi





#-----------------------------------------------------------------------------------------------------------------------------------
# Version Print
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_version_print()
{
    version_print
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Help Print
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_help_print()
{
    mpm_version_print
    echo_error "Repository URL: [${MPM_REPO}]"
    help_print
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Arg Parse
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_args_parse()
{
    tmp_args=$(getopt -o hi:lr:TvV --long help,install:,list,repo:,test,verbose,version -n "${NAME}" -- "$@")

    if [ $? != 0 ]; then echo_error "Terminating..." >&2; exit 1; fi

    eval set -- "${tmp_args}"

    while true
    do
        case "$1" in
            # Path options
            -r|--repo)       MPM_REPO="$2";                              shift; shift;;

            # Mode switches
            -h|--help)       MODE="EXIT";    mpm_help_print;                    shift;;
            -i|--install)    MODE="INSTALL"; MPM_NAME="$2";              shift; shift;;
            -l|--list)       MODE="LIST";                                       shift;;
            -V|--version)    MODE="EXIT";    mpm_version_print;                 shift;;

            # Global options
            -T|--test)       DRY_RUN="TRUE";                                    shift;;
            -v|--verbose)    VERBOSE="TRUE";                                    shift;;

            # End of options
            --)                                                          shift;  break;;
            *) echo_error "args_parse internal error [$1]!";                          exit 1;;
        esac
    done

    if [[ "${MODE}" == "DEFAULT" ]]
    then
        MODE="EXIT"

        echo_error "Help, Install, List or Version should be invoked!"
        mpm_help_print
        
        exit 1
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Meta Package List
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_mpkg_list()
{
    if [[ "${MPM_REPO}" =~ ^https?:// ]]
    then
        cmd_exec curl -L "${MPM_REPO}" 2>/dev/null | grep -e '\.mpm</a>' | sed -e 's/.*href="//' -e 's/\.mpm".*//'
    else
        ls "${MPM_REPO}"/*.mpm | sed -e "s%^${MPM_REPO}/%%" -e 's/\.mpm$//'
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Meta Package Tag Read
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_mpkg_tag_read()
{
    local  mpkg="$1"
    local   tag="$2"

    if [[ "${MPM_REPO}" =~ ^https?:// ]]
    then
        cmd_exec curl -L "${MPM_REPO}/${mpkg}.mpm" 2>/dev/null | grep -e "${tag}: " | sed -e "s/^${tag}: //"
    else
        grep -e "${tag}: " "${MPM_REPO}/${mpkg}.mpm" 2>/dev/null | sed -e "s/^${tag}: //"
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Meta Package Description
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_mpkg_desc()
{
    local mpkg="$1"

    mpm_mpkg_tag_read "${mpkg}" "PKG_DESC"
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Meta Package Package List
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_mpkg_pkglist()
{
    local mpkg="$1"

    mpm_mpkg_tag_read "${mpkg}" "PKG_LIST"
}





#-----------------------------------------------------------------------------------------------------------------------------------
# List
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_list()
{
    local    mpkg
    local    desc
    local pkglist

    echo "            MPM Name | MPM Description                  | Package List                                                              "
    echo "---------------------+----------------------------------+---------------------------------------------------------------------------"

    mpm_mpkg_list | while read -r mpkg
    do
        desc="$(mpm_mpkg_desc "${mpkg}")"
        pkglist="$(mpm_mpkg_pkglist "${mpkg}")"

        printf "%20s | %-32s | %s\n" "${mpkg}" "${desc}" "${pkglist}"
    done
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Install
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_install()
{
    local    mpkg="$1"
    local pkglist

    
    if [[ "${mpkg}" == "" ]]
    then
        echo_error "Missing required mpkg name!"
        
        exit 1
    fi

    mpm_mpkg_list | grep -qe "^${mpkg}$" -e "^${mpkg} " -e " ${mpkg}$" -e " ${mpkg} "

    if [[ "$?" == "1" ]]
    then
        echo_error "mpkg [${mpkg}] not found!"

        exit 1
    fi

    pkglist="$(mpm_mpkg_pkglist "${mpkg}")"

    if [[ "${pkglist}" == "" ]]
    then
        echo_error "Package list is empty!"

        exit 1
    fi

    echo "Installing MPM: [${mpkg}]:[${pkglist}]"

    cmd_exec urpmi --force ${pkglist}
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Main
#-----------------------------------------------------------------------------------------------------------------------------------

mpm_args_parse "$@"



if [[ "${MODE}" == "EXIT" ]]
then
    exit 0
fi

echo_error "Mode: [${MODE}]   Verbose: [${VERBOSE}]   Dry_Run: [${DRY_RUN}]   Repo_URL: [${MPM_REPO}]"

case "${MODE}" in
    LIST)
        mpm_list
    ;;

    INSTALL)
        mpm_install "${MPM_NAME}"
    ;;

    *)
        mpm_help_print
        RETVAL=1
    ;;
esac

exit ${RETVAL}
