#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
# Mk Base Image
# 
# Copyright (C) 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 General Public License for more details.
# 
# You should have received a copy of the GNU 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}/docker_tools.bash"





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

declare -g              VERSION=1.0.1
declare -g                 NAME="MBI"
declare -g                 HELP="usage: mk_base_image [[-h | --help] | [-V | --version] | [-p | --pre] | [-P | --post] | [-s | --strip] | [-u | --unstrip]] [-D | --direct] [-d | --distrib <Distrib>] [-l | --lang <Lang>] [-L | --language <Langage>] [-m | --localtime <Local_Time>] [-r | --root <Root_Dir>] [-t | --tmp <Tmp_Dir>] [-T | --test] [-v | --verbose]"

declare -g          TMP_DIR_DEF="/tmp/mk_base_image"
declare -g         ROOT_DIR_DEF="/var/tmp/base_root"

declare -g          DISTRIB_DEF="9"
declare -g             LANG_DEF="en_US.UTF-8"
declare -g         LANGUAGE_DEF="en_US.UTF-8:en_US:en"
declare -g        LOCALTIME_DEF="Europe/Paris"

declare -Ag     CONTAINER_TAB

declare -g          BUILDER_DIR="/"
declare -g             ROOT_DIR="${ROOT_DIR_DEF}"
declare -g              TMP_DIR="${TMP_DIR_DEF}"

declare -g              DISTRIB="${DISTRIB_DEF}"
declare -g                 LANG="${LANG_DEF}"
declare -g             LANGUAGE="${LANGUAGE_DEF}"
declare -g            LOCALTIME="${LOCALTIME_DEF}"
 
declare -g                 MODE="DEFAULT"
declare -g              VERBOSE="FALSE"
declare -g              DRY_RUN="FALSE"
declare -g               DIRECT="FALSE"

declare -g        NAME_SERVER_0='10.10.0.254'
declare -g        NAME_SERVER_1='8.8.8.8'





#    find / 2>/dev/null | grep -v -e "^/dev" -e "^/proc" -e "^/run" -e "^/sys/" >/root/after

#-----------------------------------------------------------------------------------------------------------------------------------
# Version
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_version_print()
{
    version_print
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Help
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_help_print()
{
    mbi_version_print
    help_print
}





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

function mbi_args_parse()
{   
    tmp_args=$(getopt -o d:Dhl:L:m:pPr:Tt:suvV --long distrib:,direct,help,lang:,language:,localtime:,pre,post,root:,test,tmp:,strip,unstrip,verbose,version -- "$@")

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

    # Note the quotes around `$tmp_args': they are essential!
    eval set -- "${tmp_args}"

    while true
    do
	case "$1" in
            
	    # Options
            -d|--distrib)                    shift;         DISTRIB="$1";                         shift;  RECALL_OPTS+=" --distrib   ${DISTRIB}";;
            -D|--direct)                                     DIRECT="TRUE";                       shift;;

	    # Local options
            -l|--lang)                       shift;            LANG="$1";                         shift;  RECALL_OPTS+=" --lang      ${LANG}";;
            -L|--language)                   shift;        LANGUAGE="$1";                         shift;  RECALL_OPTS+=" --language  ${LANGUAGE}";;
            -m|--localtime)                  shift;       LOCALTIME="$1";                         shift;  RECALL_OPTS+=" --localtime ${LOCALTIME}";;
            
	    # Path options
            -t|--tmp)                        shift;         TMP_DIR="$1";                         shift;;
            -r|--root)                       shift;        ROOT_DIR="$1";                         shift;;
            
	    # Mode switches
	    -h|--help)                                         MODE="EXIT";    mbi_help_print;    shift;;
            -p|--pre)                                          MODE="PRE";                        shift;;
            -P|--post)                                         MODE="POST";                       shift;;
            -s|--strip)                                        MODE="STRIP";                      shift;;
            -u|--unstrip)                                      MODE="UNSTRIP";                    shift;;
	    -V|--version)                                      MODE="EXIT";    mbi_version_print; shift;;

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

	    #   
	    --)                                                                                   shift;  break;;
	    *) echo "args_parse internal error [$1] !"; exit 1;;
	esac
    done
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Container Tab Init
#-----------------------------------------------------------------------------------------------------------------------------------

mbi_container_tab_init()
{
    CONTAINER_TAB["Builder,Name"]="rx3-builder"
  CONTAINER_TAB["Builder,Source"]="docker.io/library/mageia:${DISTRIB_DEF}"
       CONTAINER_TAB["Root,Name"]="rx3-mageia${DISTRIB}"
     CONTAINER_TAB["Root,Source"]="scratch"
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Env Init
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_env_init()
{
    root_clean="$1"


    if [[ -d "${TMP_DIR}" ]]
    then
        echo_error "Removing Tmp Dir: [${TMP_DIR}] content..."
        cmd_exec echo rm -R "${TMP_DIR}/*"
    else
        echo_error "Creating Tmp Dir: [${TMP_DIR}]..."
        cmd_exec mkdir -p "${TMP_DIR}"
    fi
    
    if [[ "${DIRECT}" == "TRUE" ]]
    then
        if [[ -d "${ROOT_DIR}" ]]
        then
            if [[ "${root_clean}" == "TRUE" ]]
            then
                echo_error "Removing Root Dir: [${ROOT_DIR}] content..."
                sh_exec echo rm -R "${ROOT_DIR}/*"
            else
                echo_error "Keeping Root Dir content..."
            fi
        else
            if [[ "${root_clean}" == "TRUE" ]]
            then
                echo_error "Creating Root Dir: [${ROOT_DIR}]..."
                cmd_exec mkdir -p "${ROOT_DIR}"
            else
                echo_error "Error: Root Dir: [${ROOT_DIR}] not found!"
                exit 1
            fi    
        fi
    else
        for container_id in "Builder" "Root"
        do
            container_name="${CONTAINER_TAB["${container_id},Name"]}"
                
            if [[ "${root_clean}" == "TRUE" ]]
            then
                if [[ $( buildah ls | grep ${container_name}) != "" ]]
                then
                    sh_exec "buildah rm \"${container_name}\" >/dev/null"
                fi

                sh_exec "buildah from   --name \"${container_name}\" \"${CONTAINER_TAB[${container_id},Source]}\" >/dev/null"
                sh_exec "buildah config --label maintainer=\"Arnaud G. GIBERT <arnaud@rx3.net>\" \"${container_name}\""
            else
                if [[ $( buildah ls | grep ${container_name}) == "" ]]
                then
                    echo_error "buildah container: [${container_name}] not found!"
                    exit 1
                fi
            fi
        done
        
        if [[ "${BUILDAH_ISOLATION:-}" != "rootless" ]]
        then
            echo_error "Unsharing..."

            cmd_exec buildah unshare "$0" ${ORIG_ARGS[@]}
            exit $?
        else
            BUILDER_DIR=$(buildah mount ${CONTAINER_TAB["Builder,Name"]})
               ROOT_DIR=$(buildah mount ${CONTAINER_TAB["Root,Name"]})

            echo_error "Making Builder..."

            cmd_exec                         cp /etc/resolv.conf "${BUILDER_DIR}/etc/resolv.conf"
            cmd_exec chroot "${BUILDER_DIR}" bash -c 'curl -L http://mirror.rx3.net/rx3/cgi-bin/urpmi-setup-dump.cgi?'${DISTRIB}' | bash'
            cmd_exec chroot "${BUILDER_DIR}" urpmi --force rx3-base
        fi
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Env DeInit
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_env_deinit()
{
    if [[ -d "${TMP_DIR}" ]]
    then
        echo_error "Removing Tmp Dir: [${TMP_DIR}] content..."
        cmd_exec echo rm -R "${TMP_DIR}/*"
    fi

    if [[ "${DIRECT}" != "TRUE" ]]
    then
        container_name="${CONTAINER_TAB["Builder,Name"]}"
          
        if [[ $( buildah ls | grep ${container_name}) != "" ]]
        then
            sh_exec "buildah umount \"${container_name}\" >/dev/null"
            sh_exec "buildah rm     \"${container_name}\" >/dev/null"
        fi
        
        container_name="${CONTAINER_TAB["Root,Name"]}"
          
        if [[ $( buildah ls | grep ${container_name}) != "" ]]
        then
            sh_exec "buildah commit \"${container_name}\" >/dev/null"
        fi
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Base Install Pre
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_base_install_pre()
{
    if [[ "${DIRECT}" == "FALSE" ]]
    then
        echo_error "Chrooting in Builder_Dir: [${BUILDER_DIR}] for Pre-Install.."
        
        cmd_exec mkdir -p "${BUILDER_DIR}/${ROOT_DIR_DEF}"
        cmd_exec mount --bind "${ROOT_DIR}" "${BUILDER_DIR}/${ROOT_DIR_DEF}"

        chroot_cmd="chroot ${BUILDER_DIR}"
        root_dir="${ROOT_DIR_DEF}"
    else
        echo_error "Direct Pre-Install..."
        
        chroot_cmd=""
        root_dir="${ROOT_DIR}"
    fi


    cmd_exec ${chroot_cmd} bash -c 'rm /var/cache/urpmi/rpms/* || true'

    cmd_exec ${chroot_cmd} urpmi --root ${root_dir} --force --no-install --no-recommends --nolock --reinstall --download-all ${TMP_DIR} --downloader curl makedev filesystem curl urpmi rx3-base

    cmd_exec ${chroot_cmd} bash -c 'rpm   --root '${root_dir}' --initdb'
    cmd_exec ${chroot_cmd} bash -c 'rpm   --root '${root_dir}'  -Uvh --nodeps --noscripts '${TMP_DIR}'/rpms/filesystem*'
    cmd_exec ${chroot_cmd} bash -c 'rm                                                    '${TMP_DIR}'/rpms/filesystem*'

    cmd_exec ${chroot_cmd} bash -c 'rpm   --root '${root_dir}'  -Uvh --nodeps --noscripts '${TMP_DIR}'/rpms/makedev*'
    cmd_exec ${chroot_cmd} bash -c 'rm                                                    '${TMP_DIR}'/rpms/makedev*'

    cmd_exec ${chroot_cmd} bash -c 'rpm   --root '${root_dir}'  -Uvh --nodeps             '${TMP_DIR}'/rpms/*'
    cmd_exec ${chroot_cmd} bash -c 'rm                          -R                        '${TMP_DIR}

    # Enable Neworking
    sh_exec               'echo -e "nameserver '${NAME_SERVER_0}'\nnameserver '${NAME_SERVER_1}'"  >"'${ROOT_DIR}'/etc/resolv.conf"'
    sh_exec               'echo -e "NETWORKING=yes"                                                >"'${ROOT_DIR}'/etc/sysconfig/network"'

    if [[ "${DIRECT}" == "FALSE" ]]
    then      
        cmd_exec umount "${BUILDER_DIR}/${ROOT_DIR_DEF}"
    fi
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Base Install Post
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_base_install_post()
{
    
    cmd_exec chroot ${ROOT_DIR} urpmi-setup --verbose --distrib "${DISTRIB}"
    
    cmd_exec chroot ${ROOT_DIR} urpmi --force --auto-update
    
    cmd_exec chroot ${ROOT_DIR} urpmi --force basesystem-minimal locales locales-en shared-mime-info vim-minimal mpm

    sh_exec                    'echo -e "LANG='${LANG}'\nLANGUAGE='${LANGUAGE}'" >"'"${ROOT_DIR}"'/etc/locale.conf"'
    cmd_exec chroot ${ROOT_DIR} ln   -s /usr/share/zoneinfo/${LOCALTIME}      "/etc/localtime"
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Base Strip
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_base_strip()
{
    # RPM force uninstall
    cmd_exec chroot ${ROOT_DIR} rpm -e --nodeps cracklib-dicts
    cmd_exec chroot ${ROOT_DIR} rpm -e          dhcp-common dhcp-client cronie-anacron

    # Docker mounts tmpfs at /dev and procfs at /proc so we can remove them
    cmd_exec                    rm    -rf "${ROOT_DIR}"/dev "${ROOT_DIR}"/proc                                            2>/dev/null
    cmd_exec                    mkdir -p  "${ROOT_DIR}"/dev "${ROOT_DIR}"/proc                                            2>/dev/null

    # Keep only en_US.UTF8 locale
    cmd_exec                    rm -rf "${ROOT_DIR}"/usr/share/locale/!("en_US.UTF-8"|"locale.alias"|"locale-archive")
    
    cmd_exec                    rm -rf "${ROOT_DIR}"/usr/{{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}

    #  Docs
    cmd_exec                    rm -rf "${ROOT_DIR}"/usr/share/{man,doc,info,gnome/help}

    #  sln
    cmd_exec                    rm -rf "${ROOT_DIR}"/sbin/sln

    #  ldconfig
    cmd_exec                    rm    -rf            "${ROOT_DIR}"/etc/ld.so.cache      "${ROOT_DIR}"/var/cache/ldconfig
    cmd_exec                    mkdir -p --mode=0755                                    "${ROOT_DIR}"/var/cache/ldconfig

    # UDev
    cmd_exec                    rm    -rf            "${ROOT_DIR}"/usr/lib/udev
    cmd_exec                    rm    -rf            "${ROOT_DIR}"/etc/udev/hwdb.bin

    cmd_exec                    rm    -rf            "${ROOT_DIR}"/usr/lib/.build-id

    # Cache & Tmp
    cmd_exec                    rm    -rf            "${ROOT_DIR}"/var/cache/urpmi/rpms                                   2>/dev/null
    cmd_exec                    rm    -rf            "${ROOT_DIR}"/tmp/*
}





#-----------------------------------------------------------------------------------------------------------------------------------
# Base UnStrip
#-----------------------------------------------------------------------------------------------------------------------------------

function mbi_base_unstrip()
{
    cmd_exec chroot ${ROOT_DIR} urpmi.update -a
    
    # Install uninstalled packages
    cmd_exec chroot ${ROOT_DIR} urpmi --force               cracklib-dicts dhcp-common dhcp-client cronie-anacron
    
    # Force reinstall all packages
    cmd_exec chroot ${ROOT_DIR} urpmi --force --replacepkgs $(rpm -qa | grep -v gpg-pubkey)    
}





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

ORIG_ARGS=("$@")

 
for var in $(env | grep -e LC_); do unset ${var/=*/}; done
export LC_ALL="C"



mbi_args_parse "$@"

mbi_container_tab_init


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


echo_error "MBI: Mode: [${MODE}]   Verbose: [${VERBOSE}]   Distrib: [${DISTRIB}]   Direct: [${DIRECT}]   Dry_Run: [${DRY_RUN}]   Lang: [${LANG}]   Language: [${LANGUAGE}]   Local_Time: [${LOCALTIME}]   Builder_Dir: [${BUILDER_DIR}]   Root_Dir: [${ROOT_DIR}]   Tmp_Dir: [${TMP_DIR}]"


if [[ "${MODE}" == "DEFAULT" ]]
then
        mbi_env_init "TRUE"
else
        mbi_env_init "FALSE"
fi


case "${MODE}" in
            
    "DEFAULT")
        mbi_base_install_pre
        mbi_base_install_post
        mbi_base_strip
        mbi_env_deinit
    ;;

    "PRE")
        mbi_base_install_pre
    ;;

    "POST")
        mbi_base_install_post
    ;;

    "STRIP")
        mbi_base_strip
    ;;

    "UNSTRIP")
        mbi_base_unstrip
    ;;
    
esac
