#!/usr/bin/env bash

# import gentoo functions

source /lib/gentoo/functions.sh

# generic variables

export releasename="argent"
export releasetarget="ws"
export releaseversion="1"

# kernel version && name from inside core squashfs

export kernelver="6.12.9-"$releasename""

# core squahfs name and md5 checksum file

export chrootx64=""$releasename"_"$releasetarget"_"$releaseversion"_core_x64.squashfs"
export chrootx64md5=""$chrootx64".md5"

# overlay mount variables

export rodir="rodir"
export rwdir="rwdir"
export workdir="workdir" # only needed for overlayfs on kernel greather than 3.18
export overlaydir="overlaydir"

# build variables and commands to run inside core squashfs when building packages

export chrootuser="root"
export chroottarget="${@:2}"
export chrootbuildtarget="emerge -kav "$chroottarget""
export chrootsrcmode="avasile --srcmode"

# iso variables and commands to run inside core squahfs when making iso image

export isouser="root"
export isomainarch="x86_64"
export isobinmode="avasile --usermode"
export isokernelname="kernel-genkernel-"$isomainarch"-"$kernelver""
export isoramfscmd="dracut -N -a dmsquash-live -a pollcdrom -a mdraid -o systemd -o systemd-initrd -o systemd-networkd -o dracut-systemd -o btrfs -o crypt -o i18n -o usrmount -o lunmask -o nvdimm -o multipath -I busybox --force --kver "$kernelver" /boot/initramfs-genkernel-"$isomainarch"-"$kernelver""
export isoramfsname="initramfs-genkernel-"$isomainarch"-"$kernelver""
export isoeficmd="grub-mkimage -d /usr/lib/grub/x86_64-efi -o bootx64.efi -O x86_64-efi ext2 fat udf btrfs ntfs reiserfs xfs hfsplus lvm ata part_msdos part_gpt part_apple bsd search_fs_uuid normal chain iso9660 configfile help loadenv reboot cat search memdisk tar boot linux chain -p /boot/grub"
export isochainloadcmd="grub-mkimage -d /usr/lib/grub/i386-pc -o core.img -O i386-pc biosdisk part_msdos fat -p /boot/grub"

# iso image layout variables

export bootloaderfetchpath="/tmp/bootcore"
export bootloaderconfigs=""$bootloaderfetchpath"/cdroot/boot"
export isorootdir=""$releasename"-"$releasetarget"-"$releaseversion"-"$isomainarch""
export isogrubdir=""$isorootdir"/boot/grub"
export isoefidir=""$isorootdir"/efi/boot"
export isorsynctarget=""$isorootdir"/rootfs"
export isorsyncsource="/tmp/"$isorootdir""
export isocdrootdir=""$isorootdir"/CDroot"
export isorealfsdir=""$isocdrootdir"/LiveOS"
export isosquashfsdir=""$isorootdir"/LiveOS"

# modechange variables

export portagedir="/var/db/repos/gentoo"
export argentdir="/var/db/repos/argent-ws"
export confdir="/etc/portage"
export gitdir="/opt/argentws-build/conf/intel/portage"
export clonedir="/opt/argentws-build"

# Support SUDO for avasile
export ARGENT_USE_SUDO="${ARGENT_USE_SUDO:-0}"

# generic functions (used for both build && iso creation)

kernelconfig () {
	# check if the host kernel has needed modules for avasile to work properly...fail to start if it doesn't
	if [[ $(zgrep 'CONFIG_OVERLAY_FS=' /proc/config.gz) && $(zgrep "CONFIG_SQUASHFS=" /proc/config.gz) &&  $(zgrep "CONFIG_BLK_DEV_LOOP=" /proc/config.gz) ]] ; then
		einfo "Kernel configuration seems OK, moving on"
		sleep 1
	else
		eerror "Vasile needs OVERLAYFS && SQUASHFS && LOOP DEVICES to work"
		eerror "Please rebuild the kernel with those activated to use it"
		exit 1
	fi
}

checkmode() {
	CHECK_AVASILE_MODE=$( readlink -f /etc/portage/make.conf )

	if [[ "${CHECK_AVASILE_MODE}" = "${clonedir}/conf/intel/portage/make.conf.amd64-user" ]] ; then
		echo "$0 is on --usermode"
	elif [[ "${CHECK_AVASILE_MODE}" = "${clonedir}/conf/intel/portage/make.conf.amd64-devel" ]] ; then
		echo "$0 is on --devmode!"
	elif [[ "${CHECK_AVASILE_MODE}" = "${clonedir}/conf/intel/portage/make.conf.amd64-srcmode" ]] ; then
		echo "$0 is on --srcmode!"
	elif [[ "${CHECK_AVASILE_MODE}" = "${clonedir}/conf/intel/portage/make.conf.amd64-custom" ]] ; then
		echo "$0 is on your own custom mode!"
	elif [[ "${CHECK_AVASILE_MODE##*-}" != "user" ]] || [[ "${CHECK_AVASILE_MODE##*-}" != "devel" ]] || \
		[[ "${CHECK_AVASILE_MODE##*-}" != "srcmode" ]] || [[ "${CHECK_AVASILE_MODE##*-}" != "custom" ]] ; then
		echo "$0 is not on any known modes"
	fi
}

checkroot () {
	# check for root privileges, needed for mount && chroot...fail to start if not root
	if [[ "${UID}" != "0" ]] ; then
		eerror "You're not root user? Perhaps you have 'sudo', although not security-wise."
		echo -e ""
		if [[ -x "$(command -v sudo)" ]] ; then
		    sudo "$0" "$@"
		else
		    eerror "You do not have sudo either. Exitting."
		    echo -e ""
		    exit 1
		fi
	fi
}

checkiflive () {
	# check if running in live mode...fail to start if so
	if [[ -L /dev/mapper/live-base ]] ; then
		eerror "Running in Live mode is unsupported"
		exit 1
	fi
}

chrootchecksum () {
	# check if core squashfs and md5 checksum file exists, verify core squashfs integrity against md5 checksum file
	# fail to start if core squashfs or md5 checksum file doesn't exist, or if core squashfs fails md5 verification
	while : true ; do
		if [[ -f "$chrootx64" && -f "$chrootx64md5" ]] ; then
			einfo "Squashed chroot && Checksum file found"
			if [[ "$(md5sum -c "$chrootx64md5")" ]] ; then
				einfo "Squashed chroot checksum passed"
				sleep 1
				break
			else
				eerror "Squashed chroot checksum failed"
				exit 1
			fi
		else
			eerror "Squashed chroot || Checksum file not found"
			exit 1
		fi
	done
}

# build functions

chrootprepare () {
	# always start from fresh overlay mount path, if previous exists, remove it and start over
	while : true ; do
	for dir in "$rodir" "$rwdir" "$workdir" "$overlaydir"; do
	    if [[ ! -d "$dir" ]]; then
		mkdir "$dir"
	    fi
	done

	if [[ -d "$rodir" && -d "$rwdir" && -d "$workdir" && -d "$overlaydir" ]]; then
		chrootstart
		break
	else
	chrootstop
	    for dir in "$rodir" "$rwdir" "$workdir" "$overlaydir"; do
		rm -rf "$dir"
	    done
		continue
	fi
	done

}

chrootstop () {
	# umount core squashfs overlay mount
	umount -l "$overlaydir"/proc > /dev/null 2>&1
	umount -l "$overlaydir"/sys > /dev/null 2>&1
	umount -l "$overlaydir"/dev/pts > /dev/null 2>&1
	umount -l "$overlaydir"/dev/shm > /dev/null 2>&1
	umount -l "$overlaydir"/dev > /dev/null 2>&1
	umount -l "$overlaydir"/tmp > /dev/null 2>&1
	umount -l "$overlaydir"/var/cache/binpkgs > /dev/null 2>&1
	umount -l "$overlaydir"/var/cache/distfiles > /dev/null 2>&1
	umount -l "$overlaydir" > /dev/null 2>&1
	umount -l "$rodir" > /dev/null 2>&1
}

chrootstart () {
	# mount core squashfs in overlay
	mount -t squashfs "$chrootx64" "$rodir"
	mount -t overlay -o lowerdir="$rodir",upperdir="$rwdir",workdir="$workdir" overlay "$overlaydir"
	mount -o bind packages "$overlaydir"/var/cache/binpkgs
	mount -o bind distfiles "$overlaydir"/var/cache/distfiles
	mount -t proc proc "$overlaydir"/proc
	mount -t sysfs sysfs "$overlaydir"/sys
	mount -t devtmpfs -o relatime,size=3055348k,nr_inodes=763837,mode=755 none "$overlaydir"/dev
	mount -t devpts -o nosuid,noexec,relatime,gid=5,mode=620 none "$overlaydir"/dev/pts
	mount -t tmpfs -o nosuid,nodev none "$overlaydir"/dev/shm
	mount -t tmpfs -o nosuid,nodev,noexec none  "$overlaydir"/tmp
}

chrootdevtree () {
	# inject portage tree, argent-ws overlay && argent workstation buildsystem (portage config)
	chroot "$overlaydir" su - "$chrootuser" -c "$chrootsrcmode"
}

chrootbuild () {
	# build and install package(s) given as argument...if is already built, install it
	einfo "All systems are go!"
	sleep 1
	chroot "$overlaydir" su - "$chrootuser" -c "$chrootbuildtarget"
}

chrootx64_iso () {
	# land into a chroot env into overlay mounted core squashfs and make build adjustments, if needed
	einfo "DROPPING YOU TO A ROOT SHELL INTO BUILD ENVIRONMENT"
	einfo "FIX FAILURES && ADJUST PORTAGE CONFIGURATION FILES"
	einfo "TEST USEFLAGS && KEYWORDS && MASKS IF REQUIRED"
	einfo "IN THE END : DO NOT FORGET TO COMMIT YOUR CHANGES"
	chroot "$overlaydir" su - "$chrootuser"
}

regenerate_cache () {
	env-update
	. /etc/profile
}

makepkg () {
	checkroot
	chrootchecksum
	chrootprepare
	chrootdevtree
	chrootbuild
	chrootx64_iso
	chrootstop
}

# iso functions

isostart () {
	# mount iso image core
	mount -o bind packages "$isorsynctarget"/usr/portage/packages
	mount -t proc proc "$isorsynctarget"/proc
	mount -t sysfs sysfs "$isorsynctarget"/sys
	mount -t devtmpfs -o relatime,size=3055348k,nr_inodes=763837,mode=755 none "$isorsynctarget"/dev
	mount -t devpts -o nosuid,noexec,relatime,gid=5,mode=620 none "$isorsynctarget"/dev/pts
	mount -t tmpfs -o nosuid,nodev none "$isorsynctarget"/dev/shm
	mount -t tmpfs -o nosuid,nodev,noexec none  "$isorsynctarget"/tmp
}

isostop () {
	# umount iso image core
	umount -l "$isorsynctarget"/proc > /dev/null 2>&1
	umount -l "$isorsynctarget"/sys > /dev/null 2>&1
	umount -l "$isorsynctarget"/dev/pts > /dev/null 2>&1
	umount -l "$isorsynctarget"/dev/shm > /dev/null 2>&1
	umount -l "$isorsynctarget"/dev > /dev/null 2>&1
	umount -l "$isorsynctarget"/tmp > /dev/null 2>&1
	umount -l "$isorsynctarget"/usr/portage/packages > /dev/null 2>&1
}

isousertree () {
	# inject portage tree, argent-ws overlay && argent workstation buildsystem (portage config)
	chroot "$isorsynctarget" su - "$isouser" -c "$isobinmode"
}

isoramfs () {
	# generate iso initramfs with required modules for live boot
	chroot "$isorsynctarget" su - "$isouser" -c "$isoramfscmd"
}

isoefiimg () {
	# generate efi bootloader
	chroot "$isorsynctarget" su - "$isouser" -c "$isoeficmd"
}

isochainloader () {
	# generate syslinux -> grub chainloader for unetbootin compatibility
	chroot "$isorsynctarget" su - "$isouser" -c "$isochainloadcmd"
}

isoservices () {
	# enable live iso image system services
	set -x
	for service in argentlive argent-config-vbox avahi-daemon connman cups dkms dm-event lvm2-lvmetad lvm2-monitor NetworkManager ModemManager sddm virtualbox-guest-additions ; do
		chroot "$isorsynctarget" su - "$isouser" -c "systemctl enable $service"
	done

	# small pipewire and wireplumber enable
	chroot "$isorsynctarget" su - "$isouser" -c "rm -f /etc/resolv.conf"
	chroot "$isorsynctarget" su - "$isouser" -c "ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf"
	chroot "$isorsynctarget" su - "$isouser" -c "systemctl --user disable pulseaudio.socket pulseaudio.service"
	chroot "$isorsynctarget" su - "$isouser" -c "systemctl --user enable pipewire-pulse.socket wireplumber.service"
	chroot "$isorsynctarget" su - "$isouser" -c "systemctl --user enable pipewire.service"
	set +x
}

isochroot () {
	# land into a chroot env into iso image core and make adjustments, if needed
	einfo "DROPPING YOU TO A ROOT SHELL INTO ISO ENVIRONMENT"
	einfo "INSTALL APPS & TARGETS & DES YOU WANT INSIDE ISO"
	einfo "EXIT WHEN YOU'RE DONE AND I'LL CREATE THE IMAGE"
	if [[ -z "${@:2}" ]] ; then
		chroot "$isorsynctarget" su - "$isouser"
		chroot "$isorsynctarget" su - "$isouser" -c "umount -f /mnt/argent_efipart/dev/*"
		chroot "$isorsynctarget" su - "$isouser" -c "env-update"
	else
                echo "No need to drop into shell, you provided a list to install"
                if [[ -e "$isorsynctarget/ISO_Installed_Packages" ]] ; then
                        rm -f "$isorsynctarget"/ISO_Installed_Packages
                fi
                for i in "${@:2}" ; do cat $i >> "$isorsynctarget"/ISO_Installed_Packages ; done
                mapfile -t ISO_ARGENT_PACKAGES_LIST < "$isorsynctarget"/ISO_Installed_Packages

		chroot "$isorsynctarget" su - "$isouser" -c "epkg autoinstall ${ISO_ARGENT_PACKAGES_LIST[*]} "
		chroot "$isorsynctarget" su - "$isouser" -c "umount -f /mnt/argent_efipart/dev/*"
		chroot "$isorsynctarget" su - "$isouser" -c "env-update"

		unset ISO_ARGENT_PACKAGES_LIST
	fi
}

prepareiso () {
	# prepare iso image layout
	mkdir -p "$isorsynctarget"
	dd if=/dev/zero of="$isorsynctarget.img" bs=50M count=400
	mkfs.ext4 -F "$isorsynctarget.img"
	mkdir -p "$isorsyncsource"
	mkdir -p "$isocdrootdir"
	mkdir -p "$isosquashfsdir"
	mkdir -p "$isorealfsdir"
	mkdir -p "$isogrubdir"
	mkdir -p "$isoefidir"
	# mount core squashfs and rsync it's contents into core iso image
	mount -t squashfs "$chrootx64" "$isorsyncsource"
	mount -t ext4 "$isorsynctarget.img" "$isorsynctarget"
	rsync -aHAXr --progress "$isorsyncsource/" "$isorsynctarget/"
	# copy the kernel for live boot
	if [[ ! -f "$isorsynctarget/boot/$isokernelname" ]]; then
		# Found no $isokernelname in $isorsynctarget
		dracut -H -f -o systemd -o systemd-initrd -o systemd-networkd -o dracut-systemd -o plymouth --early-microcode --kver="$kernelver" "$isorsynctarget/boot/$isokernelname"
		cp -avx "$isorsynctarget/boot/$isokernelname" "$isorootdir/boot/vmlinuz" || continue
	else
		cp -avx "$isorsynctarget/boot/$isokernelname" "$isorootdir/boot/vmlinuz"
	fi
	# generate and copy initramfs for live boot
	isostart
	isoramfs
	isostop
	echo "WE MOVE THE INITRAMFS TO INITRD..."
	ls -la "$isorsynctarget"/boot/
	mv "$isorsynctarget/boot/$isoramfsname" "$isorootdir/boot/initrd"
	echo "DONE REMOVING."
	# generate and copy efi bootloader for live boot
	isostart
	isoefiimg
	isostop
	if [[ -e "$isorsynctarget"/root/bootx64.efi ]] ; then
		mv "$isorsynctarget/root/bootx64.efi" "$isoefidir"
		chmod 755 "$isoefidir/bootx64.efi"
	else
		echo "You do not have a $isorsynctarget/root/bootx64.efi"
		echo "Please generate it yourself!"
	fi
	# generate and copy syslinux -> grub chainloader for unetbootin compatibility
	isostart
	isochainloader
	isostop
	if [[ -e "$isorsynctarget/root/core.img" ]] ; then
		mv "$isorsynctarget/root/core.img" "$isogrubdir"
	else
		echo "You do not have "$isorsynctarget/root/core.img""
		echo "Please generate it yourself!"
	fi

	if [[ -e "$isorsynctarget/usr/lib/grub/i386-pc/lnxboot.img" ]] ; then
		cp -avx "$isorsynctarget/usr/lib/grub/i386-pc/lnxboot.img" "$isogrubdir"
	else
		echo "You do not have "$isorsynctarget/usr/lib/grub/i386-pc/lnxboot.img""
		echo "Please generate it yourself!"
	fi
	# enable live iso image system services
	isostart
	isousertree
	isochroot "$@"
	isostop
	isostart
	isoservices
	isostop
	umount -l "$isorsynctarget" > /dev/null 2>&1
	# move "real" live filesystem into right place
	mv "$isorsynctarget.img"  "$isorealfsdir"
	# compress "fake" live filesystem
	mksquashfs "$isocdrootdir" "$isorootdir/squashfs.img" -b 1048576 -comp xz -Xdict-size 100%
	mv ""$isorootdir/"squashfs.img" "$isosquashfsdir"
	# dracut requires "real" ext4 live filesystem to be placed 
	# into a "fake" squashfs live filesystem as bellow :
	# /cdroot/LiveOS/squashfs.img/LiveOS/rootfs.img 
	# squashfs.img is the "fake" squashfs live filesystem
	# rootfs.img is the "real" ext4 live filesystem
}

bootloaderiso () {
	# get grub2 live boot configs and place them into right place
	git clone https://gitlab.com/"$releasename"/boot-core.git "$bootloaderfetchpath"
	cp -avx "$bootloaderconfigs" "$isorootdir"
}

cleanupiso () {
	# cleanup temporary files used during iso image layout preparation
	umount "$isorsyncsource"
	rm -rf "$isorsynctarget"
	rm -rf "$isorsyncsource"
	rm -rf "$isocdrootdir"
	rm -rf "$bootloaderfetchpath"
}

makeisoimg () {
	# create iso image
	grub-mkrescue --mbr-force-bootable -volid "ARGENT" -joliet -iso-level 3 -o "$releasename-$releasetarget-$releaseversion-$isomainarch.iso" "$isorootdir"
}

makeiso () {
	checkroot
	chrootchecksum
	prepareiso "$@"
	bootloaderiso
	cleanupiso
	makeisoimg
}

# modechange functions

removeportagetree() {
	# remove portage tree, but leave packages and distfiles directories intact
	if [ -d "${portagedir}/.git" ] ; then
		einfo "Removing gentoo portage tree excluding possible folders packages and distfiles"
		find "${portagedir}" -mindepth 1 -name "packages" -prune -o -name "distfiles" -prune -o -exec rm -rf {} \; > /dev/null 2>&1
	fi
}

removeoverlays() {
	# remove argent overlay
	einfo "Removing $releasename-$releasetarget overlay"

	if [[ -e $(command -v layman) ]] ; then
		layman -d "$releasename"-"$releasetarget" > /dev/null 2>&1
		if [[ -d "/var/lib/layman/$releasename-$releasetarget" ]] ; then
			rm -rf "/var/lib/layman/$releasename-$releasetarget" || die
		fi
	elif [[ -e "/var/db/repos/$releasename-$releasetarget" ]] ; then
		if [ -d "${argentdir}/.git" ] ; then
			einfo "Removing argent overlay tree excluding possible folders packages and distfiles"
			find "${argentdir}" -mindepth 1 -name "packages" -prune -o -name "distfiles" -prune -o -exec rm -rf {} \; > /dev/null 2>&1
		fi
	fi
}

removeportageconfig() {
	# remove argent buildsystem (portage configuration)
	einfo "Removing $releasename-$releasetarget buildsystem"
	rm "$confdir/make.conf" > /dev/null 2>&1
	rm "$confdir/make.profile" > /dev/null 2>&1
	rm "$confdir" > /dev/null 2>&1
	rm -rf "$clonedir" > /dev/null 2>&1
}

resetmode () {
	checkroot
	removeportagetree
	removeoverlays
	removeportageconfig
}

fetchportageconfig() {
	# fetch argent buildsystem (portage configuration)
	pushd /opt > /dev/null 2>&1
	einfo "Injecting "$releasename"-"$releasetarget" buildsystem"
	git clone --branch master https://gitlab.com/argent/argentws-build.git
	popd > /dev/null 2>&1
}

fetchfullportagetree() {
	# fetch full portage tree
	if [[ ! -d "${portagedir}"/.git ]] ; then
		einfo "Injecting devmode/srcmode (full) gentoo portage tree"
		cd "${portagedir}" && git init > /dev/null 2>&1
		git remote add origin https://gitlab.com/argent/portage.git
		git pull --depth=1 origin master
		git branch -u origin/master master
		rm -rf ""${portagedir}"/profiles/updates"
	fi
}

fetchfullargentbuilddir() {
	if [[ ! -e "$clonedir"/.git ]] ; then
		echo -e ""
		einfo "Injecting GIT sync to central Argent overlay. Please stand by!"
		cd "$clonedir" && git init > /dev/null 2>&1
		git remote add origin https://gitlab.com/argent/argentws-build.git
		git pull --depth=1 origin master
		git branch -u origin/master master
	fi
}

fetchminimalportagetree() {
	# fetch minimal portage tree
	# in usermode we don't want the whole tree of gentoo ebuilds
	# but we need portage profiles portage metadata && portage eclasses
	# so make a sparse-checkout, to fetch only what we need
	if [[ ! -d "${portagedir}/.git" ]] ; then
		einfo "Injecting usermode (minimal) gentoo portage tree"

		cd "${portagedir}" && git init > /dev/null 2>&1
		git remote add origin https://gitlab.com/argent/portage.git

		git config core.sparseCheckout true
		git config extensions.partialClone origin
		git config remote.origin.promisor true
		git config fetch.fsckObjects false
		git config remote.origin.partialCloneFilter blob:none

		echo "profiles/" > .git/info/sparse-checkout
		echo "metadata/" >> .git/info/sparse-checkout
		echo "eclass/" >> .git/info/sparse-checkout
		echo ".gitignore" >> .git/info/sparse-checkout

		git fetch --depth=1 origin master
		git checkout master

		git sparse-checkout init --cone
		git sparse-checkout set profiles metadata eclass .gitignore

		git reflog expire --expire=now --all
		git gc --prune=now --aggressive

		rm -rf profiles/updates
		find profiles/default/linux/ -mindepth 1 -maxdepth 1 -type d ! -name amd64 -exec rm -rf {} +
	fi
}

fetchminimalargenttree() {
	# fetch minimal portage tree
	# in usermode we don't want the whole tree of gentoo ebuilds
	# but we need portage profiles portage metadata && portage eclasses
	# so make a sparse-checkout, to fetch only what we need
	if [[ ! -d "${argentdir}/.git" ]] ; then
		einfo "Injecting usermode (minimal) argent overlay tree"

		cd "${argentdir}" && git init > /dev/null 2>&1
		git remote add origin https://gitlab.com/argent/argent-ws.git

		git config core.sparseCheckout true
		git config extensions.partialClone origin
		git config remote.origin.promisor true
		git config fetch.fsckObjects false
		git config remote.origin.partialCloneFilter blob:none

		echo "profiles/" > .git/info/sparse-checkout
		echo "metadata/" >> .git/info/sparse-checkout
		echo "eclass/" >> .git/info/sparse-checkout
		echo ".gitignore" >> .git/info/sparse-checkout

		git fetch --depth=1 origin master
		git checkout master
		git branch -u origin/master master

		git sparse-checkout init --cone
		git sparse-checkout set profiles metadata eclass .gitignore

		git reflog expire --expire=now --all
		git gc --prune=now --aggressive

		git submodule update --init --recursive --depth=1
		git submodule foreach --recursive 'git reflog expire --expire=now --all && git gc --prune=now --aggressive'

		rm -rf profiles/updates
	fi
}

fetchoverlays () {
	# fetch argent overlay
	einfo "Injecting $releasename-$releasetarget overlay"

	if [[ -e $(command -v layman) ]] ; then
		echo y | layman -f -a "$releasename"-"$releasetarget" -o https://gitlab.com/"$releasename"/"$releasename"-"$releasetarget"/raw/master/overlay.xml
	else
		emerge --sync "$releasename"-"$releasetarget"
	fi
}

setbinmodeconfig() {
	# set make.conf to binmode ( usermode ), portage will always use binary packages from binhost
	ln -sf "$gitdir" "$confdir"
	ln -sf "$confdir"/make.conf.amd64-user "$confdir"/make.conf
	# ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
	# eselect profile set "$releasename-$releasetarget:default/linux/amd64/17.0"
	eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
	env-update
	. /etc/profile
}

setmixedmodeconfig() {
	# set make.conf to devmode, portage will prefer binary packages over ebuilds
	# but will use ebuilds if they are newer than binary packages from binhost
	# or if the binary package is not available in binhost
	ln -sf "$gitdir" "$confdir"
	ln -sf "$confdir"/make.conf.amd64-devel "$confdir"/make.conf
	# ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
	# eselect profile set "$releasename-$releasetarget:default/linux/amd64/17.0"
	eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
	env-update
	. /etc/profile
}

setsrcmodeconfig () {
	# set make.conf to srcmode, portage will always use ebuilds
	ln -sf "$gitdir" "$confdir"
	ln -sf "$confdir"/make.conf.amd64-srcmode "$confdir"/make.conf
	# ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
	# eselect profile set "$releasename-$releasetarget:default/linux/amd64/17.0"
	eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
	env-update
	. /etc/profile
}

setsrcmodecustom () {
	ln -sf "$gitdir" "$confdir"
	ln -sf "$confdir"/make.conf.amd64-custom "$confdir"/make.conf
	# ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
	# eselect profile set "$releasename-$releasetarget:default/linux/amd64/17.0"
	eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
	env-update
	. /etc/profile
}

binmode() {
	resetmode
	fetchportageconfig
	fetchminimalportagetree
	fetchminimalargenttree
	setbinmodeconfig
}

mixedmode() {
	resetmode
	fetchportageconfig
	fetchfullportagetree
	setmixedmodeconfig
	fetchoverlays
}

srcmode() {
	resetmode
	fetchportageconfig
	fetchfullportagetree
	setsrcmodeconfig
	fetchoverlays
}

srccustom() {
	resetmode
	fetchportageconfig
	fetchfullportagetree
	fetchoverlays
        echo -e ""
        if [[ -e "$clonedir" ]] ; then
                if [[ ! -e "$confdir"/make.conf.amd64-custom ]] ; then
                        cp "$confdir"/make.conf.amd64-devel "$confdir"/make.conf.amd64-custom
                fi
        rm -rf "$clonedir"/.git
        rm -rf "$clonedir"/conf/intel/portage/package.keywords/*
        rm -rf "$clonedir"/conf/intel/portage/package.use/*
        fi
        echo -e ""
	setsrcmodecustom
}


decentralized_user () {
	echo -e ""
        if [[ -e "$clonedir" ]] ; then
		rm -f "$confdir"/make.conf
		ln -sf "$confdir"/make.conf.amd64-user "$confdir"/make.conf
		ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
		eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
		env-update
		. /etc/profile
	fi
	echo -e ""
}

decentralized_devel () {
	echo -e ""
	if [[ -e "$clonedir" ]] ; then
		ln -sf "$confdir"/make.conf.amd64-devel "$confdir"/make.conf
		ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
		eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
		env-update
		. /etc/profile
	fi
	echo -e ""
}

decentralized_source () {
	echo -e ""
	if [[ -e "$clonedir" ]] ; then
		ln -sf "$confdir"/make.conf.amd64-srcmode "$confdir"/make.conf
		ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
		eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
		env-update
		. /etc/profile
	fi
	echo -e ""
}

decentralized_custom () {
	echo -e ""
	if [[ -e "$clonedir" ]] ; then
		if [[ ! -e "$confdir"/make.conf.amd64-custom ]] ; then
			cp "$confdir"/make.conf.amd64-devel "$confdir"/make.conf.amd64-custom
		fi
		ln -sf "$confdir"/make.conf.amd64-custom "$confdir"/make.conf
		ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
		eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
		env-update
		. /etc/profile
	fi
	echo -e ""
}

decentralized_gentoo () {
	echo -e ""
	if [[ -e "$clonedir" ]] ; then
		if [[ ! -e "$confdir"/make.conf.amd64-custom ]] ; then
			cp "$confdir"/make.conf.amd64-devel "$confdir"/make.conf.amd64-custom
		fi
		ln -sf "$confdir"/make.conf.amd64-custom "$confdir"/make.conf
		ln -sf "$confdir"/binhost-main.conf "$confdir"/binhost.conf
		eselect profile set "default/linux/amd64/23.0/desktop/plasma/systemd"
		env-update
		. /etc/profile
	fi
	rm -rf "$confdir"/.git
	sed -i 's|!||g' "$clonedir"/conf/intel/portage/package.keywords/.gitignore
	for i in $( cat "$clonedir"/conf/intel/portage/package.keywords/.gitignore | grep keyword ) ; do
		rm -f "$clonedir"/conf/intel/portage/package.keywords/$i
	done
	sed -i 's|!||g' "$clonedir"/conf/intel/portage/package.use/.gitignore
	for i in $( cat "$clonedir"/conf/intel/portage/package.use/.gitignore | grep use ) ; do
		rm -f "$clonedir"/conf/intel/portage/package.keywords/$i
	done
	echo -e ""
}
# help menu color variables

export colorstart="\e[1;49;34m"
export colorstop="\e[0m"

# help menu function

showhelp () {

echo -e "\
"$colorstart"SYNOPSIS"$colorstop"
	"$colorstart"avasile --option"$colorstop" ["$colorstart"arguments"$colorstop"]
	"$colorstart"avasile --help"$colorstop"

"$colorstart"DESCRIPTION"$colorstop"

	Vasile is an acronym for ** Versatile Advanced Script for ISOs and Latest Enhancements **
	Avasile stands for Argent Vasile

"$colorstart"OPTIONS"$colorstop"
	"$colorstart"--status"$colorstop"
		The option shows the current state of Avasile mode ( user, devel, source, custom, non-custom )

		Standard options available are described bellow

	"$colorstart"--makepkg"$colorstop" ["$colorstart"package(s)"$colorstop"]
		This option will allow you to build a package or multiple packages in an overlayfs mounted squashfs chroot jail.

		It must be run in the folder where the squashfs chroot jail resides, or else it will fail to mount the squahfs chroot jail and build the package(s).

		The squashfs chroot jail and the md5sum checksum file are hardcored into "$colorstart"libavasile"$colorstop", but you may want to change them to suit your needs.

		You MUST provide package(s) to build as arguments, or else avasile will only mount the chroot jail

		Examples :
			"$colorstart"avasile --makepkg wine"$colorstop"
			"$colorstart"avasile --makepkg wine playonlinux q4wine"$colorstop"

		If the package(s) is/are already built, it will not build it/them again (unless newer version(s) is/are available), but install it/them into squahfs chroot jail

		If the package(s) you want to build depends on any already built package(s) it will make use of it/them to satisfy the required dependencies.

	"$colorstart"--makeiso"$colorstop"
		This option will allow you to build a live iso image based on the squashfs chroot jail.

		It must be run in the folder where the squashfs chroot jail resides, or else it will fail to rsync the contents of it and build the iso image.

		It is not fully automatic, it will only rsync the contents of the squashfs chroot jail, chroot into it, and let you install packages you want into the iso image.
		There are some predefined package sets available in "$colorstart"/etc/portage/sets"$colorstop". Adjust them to suit your needs.

		It will ALLWAYS use package(s) built with "$colorstart"--makepkg"$colorstop" option. When you are happy with package selection, just exit the chroot environment and
		the live filesystem will be compressed, live services will be autoenabled, live bootloader autoconfigured and in the end live iso image will be built. You will find
		a list of predefined live services list hardcoded into "$colorstart"libavasile"$colorstop". Adjust it to suit your needs.

		If used like: "$colorstart"--makeiso"$colorstop" <filename_with_packagenames>, it will create a list and automatically install your packages
		Example: "$colorstart"avasile --makeiso /etc/portage/sets/artwork "$colorstop", will install all artwork packages in the specific set

	"$colorstart"--resetmode"$colorstop"
		This option will allow you to reset the system state. It will remove whole portage tree, overlays and portage configuration files and reset the system profile. Usually
		you will never want to call this option directly, unless you really really really know what are you doing. It is called automatically when switching to other states.

		!!! WARNING !!! : Never never never leave the system in this state. You will no longer be able to install/remove/upgrade any packages untill you set the system profile,
		get the portage tree, overlays and configure portage by hand. Or, you can always activate one of the three other supported system states.

	"$colorstart"--usermode"$colorstop"
		This option will allow you to change the system state to binmode (usermode). In this state portage will allways use only binary packages from the binhost. It will fetch a minimal
		portage tree without any ebuilds in it, but only with portage profiles, metadata and eclass. It will also fetch overlay and portage configuration files, and will adjust
		"$colorstart"make.conf"$colorstop" for binary only usage. This system state is for those who just meet with the power of Gentoo.

		!!! WARNING !!! : Never never never modify or create any file in "$colorstart"/etc/portage/"$colorstop" in this state.

	"$colorstart"--devmode"$colorstop"
		This option will allow you to change the system state to mixedmode (devmode). In this state portage will prefer binary packages from the binhost over ebuilds from the portage tree.
		It will fetch the full portage tree, the overlay and portage configuration files, and adjust "$colorstart"make.conf"$colorstop" for binary/ebuild usage. Usually you will find this system state
		useful if you want to install a package not available in the binhost, you want to upgrade a package to a newer version from portage tree or if you wanna rebuild a package
		with your own useflags.

		!!! WARNING !!! : Never never never modify any file in "$colorstart"/etc/portage/"$colorstop" in this state. If you want to adjust useflags or keywords for a package, you can create a new file
		e.g.: "$colorstart"100-my.package.use"$colorstop" in "$colorstart"/etc/portage/package.use/"$colorstop" or "$colorstart"100-my.package.keywords"$colorstop" in "$colorstart"/etc/portage/package.keywords/"$colorstop".

	"$colorstart"--srcmode"$colorstop"
		This option will allow you to change the system state to srcmode. In more clear terms, it will transform your Kogaion/Argent/Redcore system into pure Gentoo. Binary packages
		from the binhost will be ignored, and you will only install packages building from portage tree using emerge. It will fetch the full portage tree, the overlay and portage
		configuration files and adjust "$colorstart"make.conf"$colorstop" for ebuild only usage.

		This system will still be synced with main Argent overlay. Even if you do modifications, the updates will overwrite your modifications. If you want more independent make.conf, please switch to
		customsrc stance.

		!!! WARNING !!! : Only use this system state if you have a strong knowledge of Gentoo tools e.g.: "$colorstart"emerge, equery, layman, eix, qlist, useflags, keywords, masks"$colorstop"
	"$colorstart"--custom"$colorstop"
		This option will allow you to change the system state to customsrc. It will change the system from standard Argent system to custom made Gentoo-specific system. Binary packages
		from the main repository will be optional, hence if you have the Argent main repository set, you will receive precompiled packages. But if your USE flags have changed, your packages will
		automatically be recompiled.

		In this system state you can modify all the USE flags, and have the full Gentoo system available at your side.

	"$colorstart"--decentralize-user"$colorstop"
		This option will allow you to change to decentralized user stance. That means you are free to decide and modify your own precompiled Gentoo system without depending on our
		central repositories. It is a highly-advanced stance that requires advanced to expert Gentoo knowledge with precompiled binaries and binhost.conf file.

		It will decentralize your system from the main Argent repository and maintain your previous changes at modes switch ( between decentralized modes only! )
		After each decentralized mode switch, you must run either "$colorstart"epkg update"$colorstop" or emerge --sync in order to still receive Argent changes!
	"$colorstart"--decentralize-dev"$colorstop"
		This option will allow you to switch to decentralized development stance. That means you are free to decide and modify your own USE flags and anything that is Gentoo related
		in your /etc/portage, but prioritize remote precompiled binary packages that come from your binhost.conf configuration.

		It will decentralize your system from main Argent repository and maintain your previous changes at modes switch ( between decentralized modes only! )
		After each decentralized mode switch, you must run either "$colorstart"epkg update"$colorstop" or emerge --sync in order to still receive Argent changes!
	"$colorstart"--decentralize-source"$colorstop"
		This option will allow you to switch to decentralized source only stance. That means you are free to decide and modify everything in /etc/portage as long as you have some
		Gentoo expert knowledge. This stance will no longer prioritize Argent precompiled binaries, and instead use source-only ebuilds that are present on your system.

		It will decentralize your system from main Argent repository and maintain your previous changes at modes switch ( between decentralized modes only! )
		After each decentralized mode switch, you must run either "$colorstart"epkg update"$colorstop" or emerge --sync in order to still receive Argent changes!

	"$colorstart"--decentralize-custom"$colorstop"
                This option will allow you to change the system state to customsrc. It will change the system from standard Argent system to custom made Gentoo-specific system. Binary packages
                from the main repository will be optional, hence if you have the Argent main repository set, you will receive precompiled packages. But if your USE flags have changed, your packages will
                automatically be recompiled.
                In this system state you can modify all the USE flags, and have the full Gentoo system available at your side.

		It will decentralize your system from main Argent repository and maintain your previous changes at modes switch ( between decentralized modes only! )
		After each decentralized mode switch, you must run either "$colorstart"epkg update"$colorstop" or emerge --sync in order to still receive Argent changes!
	"$colorstart"--decentralize-gentoo"$colorstop"
		This option will reduce your Argent's /etc/portage into pure Gentoo /etc/portage under total control of the user. That being you. The system will forget it ever was Argent before
		and considers itself "pure Gentoo". At a grand upgrade, if your Gentoo settings do not prove stable enough, the system will either fail to compile packages or not even
		start the compilation and/or upgrade. Exactly like in a usual unmaintained Gentoo where you accidentally delete your USE flags and package.keywords.

		Previous modifications are maintained. Modifications are also maintained between decentralized modes, although central authority will never be established over this stance
		or any other decentralized stance anymore. This is a one-way ticket.

		To remove this stance and become centralized again to Argent, you have to reinitialize the ArgentWS-Build GIT system in the folder:
                "$colorstart"cd /etc/portage && git init > /dev/null 2>&1
                git remote add origin https://gitlab.com/argent/argentws-build.git
                git pull --depth=1 origin master
                git branch -u origin/master master"$colorstop"

		This has a fallback on decentralize-custom."
echo -e ""
exit 0
}
