#!/bin/bash
# barium helper scripts
# author: rosalinux.ru: betcher_
if [ -f $(dirname $0)/lib ] ;  then
    . $(dirname $0)/lib
else 
    . $(which lib) || exit
fi

HLP(){
echo "
Usage:
	$(basename $0) module - unpack one step into deep (default)
Keys:
	-a - unpack to simple atomic modules
	-d - unpack to atomic dirs 
" >&2
exit 1
}

extract_simple () {
#unsquashfs simple squashfs  
	[ "$dir" ] || dir="./"
	dir="$dir/$(basename $1 |sed "s/\.${EXT}$//")" 
	mkdir -p "$dir"
    eval unsquashfs -f -dest "${dir}" "$1" $noprogress $useproc "$devnull" 
    exitmsg "Unsquashfs error" $? 
	return 0 # need zero exit code
 }

extract_contaner () {
#extract all packages from contaner
local INDEX='' UNION='' CHANGES='' SPACE='' LINDEX='' CHANGES=''
dir="$(basename $1 |sed "s/\.${EXT}$//")"
submods=$(barium modinfo $1 |sed -n '/Submodules/ s/^Submodules:\ *//p')
for m in $submods ; do
	if [ "$MODE" ] ; then 
		echo "$submods" | grep -q  "${m}/" && continue
    else
		echo "$m" |grep -q '/' && continue
    fi
    eval echo  "submodule: $m    -- processing..." $devnull
    m=$(echo $m |sed 's#/#/submod/mount/#g')
    for a in $(make_union $(prepare_layers LIST="$(realpath "$1")")); do
		local |grep  -q "$(echo "$a" |cut  -f1 -d=)" &&  eval "$a"
	done
    cat "${UNION}${METAINFODIR}/mount/${m}/pfs.files" | while read F; do 
		touch "${UNION}/$F" 
		if ! [ -e "$CHANGES/$F" ] ; then
			pushd   "${TMPSQFS}/${LINDEX}/$(basename "$1")" >/dev/null
			cp -a --parents "$(echo "$F" |sed 's:^/::')" "${UNION}/"
			popd  >/dev/null
		fi
	[ -e "$CHANGES/$F" ] || echo "Warning. Cannot extract $F"
    done
    emp="${UNION}${METAINFODIR}/mount/${m}/pfs.dirs.empty"
    [ -f "$emp" ] && cat "$emp" | while read F; do 
		F=$(echo $F |sed s':\$::')
		if [ -d "$UNION/$F" ] ; then
			touch "$UNION/$F"
		else
			echo "$F - is not directory"
		fi
    done
	cp -a ${UNION}/${METAINFODIR}/mount/${m}/unique/*  "${UNION}/" 2>/dev/null 
	touch ${UNION}/${METAINFODIR}
	if [ -d "${UNION}/${METAINFODIR}/mount/$m/submod/mount" ] ; then
		cp -fr "${UNION}/${METAINFODIR}/mount/$m/submod/mount"  "${CHANGES}/${METAINFODIR}/"  
	else 
		# сохраняем спеки
		mkdir -p "${UNION}/${METAINFODIR}/mount/$(basename $m)"
		find "${UNION}/${METAINFODIR}/mount/$m/" -type f | while read file ; do
			[ "$(basename $file)" = 'pfs.files' -o "$(basename $file)" = 'pfs.dirs.empty' ] && continue 
			cp -f  "$file" "${CHANGES}/${METAINFODIR}/mount/$(basename $m)/"
		done
	fi
	umount $UNION
	clear_CHANGES	
	if [ "$TODIR" ] ; then
		dirname="$(realpath ${OUTDIR})/${dir}/$(basename $m)"
		[ -d "$dirname" ] && dirname="$(realpath ${OUTDIR})/${dir}/$(basename $m)_$RANDOM"
		mkdir -p "$(realpath ${OUTDIR})/${dir}" 
		cp -fax "${CHANGES}" "${dirname}"
	else
		modname="$(realpath ${OUTDIR})/${dir}/"$(basename $m)".$EXT"
		[ -f "$modname" ] && modname="$(realpath ${OUTDIR})/${dir}/"$(basename $m)_$RANDOM".$EXT"
		mkdir -p "$(realpath ${OUTDIR})/${dir}/"
		mksquashfs "$CHANGES" "$modname" ${SQFSOPT}  -noappend
    fi

    destroy_union $INDEX
	destroy_layers $LINDEX
done 
}

[ "$1" ] || HLP

#get opts
sourcelist=''
sep=''
OUTDIR='./'
for arg in $@
do
  case "${arg}" in
    "-o" | "--out-dir") shift ; OUTDIR="$1";;
    "-a" | "--atomic") MODE=atomic ;;
    "-d" | "--todir") TODIR=yes ;;
    "-h" | "--help")  HLP ;;
    "-q" | "--quiet" ) devnull='>/dev/null' ;;
    "--sqfs" )  shift
				SQFSOPT="$@"
				break ;;
    "-"*[A-Za-z]*) 	echo "$(basename "$0"): invalid option: '$(echo ${arg})'" >&2 
					HLP;;
    *) 	sourcelist="${sourcelist}${sep}${arg}"
		sep='#'
  shift
  esac
done

root_only

echo $sourcelist |sed 's/#/\n/g' |while read module ; do
	if ! file "$module" |grep -iq squashfs ; then
		echo "$module is not squashfs module"
		continue
	fi
	if [ "$(unsquashfs -l ${module} |grep ${METAINFODIR}/mount |grep -E '.files$' |wc -l)" -lt 2 ] ; then
		extract_simple $module
	else
		extract_contaner $module
	fi
done
