#!/bin/bash
#
# This is an sdm plugin for: copyfile
#
# The plugin is called three times: for Phase 0, Phase 1, and post-install.
#

function loadparams() {
    source $SDMPT/etc/sdm/sdm-readparams
}

function geninstance() {
    #
    # make a unique instance name for the run-files
    #
    local from="$1" to="$2" instance
    [ "$from" != "" ] && instance="$from-$to"
    echo "${instance//\/}"    # Remove slashes
}

function p0copyfile() {
    #
    # Handle the Phase 0 part of copying a file
    # Copies the file into the IMG and saves all the info
    # so it can be moved to its destination with the correct
    # protection and owner
    #
    local src=$1 dest=$2 owner=$3 mode=$4 mkdirif=$5 phase=$6
    local bn=$(basename $src) spath=$(dirname $src)
    local dbn="$dest/$bn"
    local dirflag
    spath=${spath//\/} # src path with slashes removed
    [ "$phase" == "" ] && phase="phase1"
    if [ "$mkdirif" != "" ]
    then
	dirflag="mkdir-${dest//\/}"   # strip slashes to make a nice flag file name
	touch $assetdir/$dirflag
    fi
    runfile="$assetdir/run-$phase-$(geninstance $src $dest)"
    [ -f $runfile ] && logtoboth "% Plugin $pfx: Over-writing previous copy of '$src' to '$dest'"
    logtoboth "> Plugin $pfx: Add '$src' to files to copy"
    logtoboth "> Plugin $pfx: Copy '$src' to '$assetdir/$spath'"
    mkdir -p $assetdir/$spath
    cp -a $src $assetdir/$spath/$bn
    # NOTE: can't use $assetdir in runfile b/c $SDMPT will be wrong for phase1/postinstall
    cat > $runfile <<EOF
#!/bin/bash
source \$SDMPT/etc/sdm/sdm-readparams
logtoboth "> Plugin $pfx: Process file '$src'"
if [ ! -d $dest ]
then
    if [ -f $dest ]
    then
        logtobothex "? Plugin $pfx: Destination '$dest' is a file but must be a directory"
    else
	dirflag="mkdir-${dest//\/}"   # strip slashes to make a nice flag file name
	[ -f /etc/sdm/assets/copyfile/$dirflag ] || logtobothex "? Plugin $pfx: Destination directory '$dest' does not exist and mkdirif not specified"
    fi
    logtoboth "> Plugin $pfx: Create destination directory '$dest'"
fi
mkdir -p $dest
logtoboth "> Plugin $pfx: Copy '$bn' from /etc/sdm/assets/copyfile/$spath to '$dest'"
cp -a /etc/sdm/assets/copyfile/$spath/$bn $dest
EOF
    chmod 755 $runfile
    if [ "$owner" != "" ]
    then
	cat >> $runfile <<EOF
if [ -f $dbn ]
then
    logtoboth "> Plugin $pfx: Set file '$dbn' owner '$owner'"
    chown $owner $dbn
fi
EOF
    fi
    if [ "$mode" != ""  ]
    then
	cat >> $runfile <<EOF
if [ -f $dbn ]
then
    logtoboth "> Plugin $pfx: Set file '$dbn' protection '$mode'"
    chmod $mode $dbn
fi
EOF
    fi
}

# $1 is the phase: "0", "1", or "post-install"
# $2 is the argument list: arg1=val1|arg2=val2|arg3=val3| ...
#
# Main code for the Plugin
#
phase=$1
pfx="$(basename $0)"     #For messages
args="$2"
loadparams
vldargs="|from|to|filelist|chown|chmod|mkdirif|runphase|"
rqdargs=""
assetdir="$SDMPT/etc/sdm/assets/copyfile"


# either from+to OR list needs to be provided. Both is also supported
# Copy file(s) to assets/copyfile during phase 0 and build a script (assets/copyfile/run_x) to copy/chown/chmod them later
#

if [ "$phase" == "0" ]
then
    #
    # In Phase 0 all references to directories in the image must be preceded by $SDMPT
    #
    logtoboth "* Plugin $pfx: Start Phase 0"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs" || exit
    plugin_printkeys
    if [ "$filelist" == "" ]
    then
	[[ "$from" == "" ]] || [[ "$to" == "" ]] && logtobothex "? Plugin $pfx: Nothing to do! One or both of 'from' or 'to' missing and no 'filelist' provided"
    fi
    if [ "$runphase" != "" ]
    then
	runphase="${runphase,,}"
	if ! [[ "|phase1|postinstall|" =~ "$runphase" ]]
	then
	    logtoboth "% Unrecognized 'runphase' value '$runphase'; assuming 'phase1'"
	    runphase="phase1"
	fi
    fi
    mkdir -p $assetdir
    if [[ "$from" != "" ]] && [[ "$to" != "" ]]
    then
	[ -v mkdirif ] && mkdirif="yes"
	p0copyfile "$from" "$to" "$chown" "$chmod" "$mkdirif" $runphase
    fi
    if [ "$filelist" != "" ]
    then
	if [ -f $filelist ]
	then
	    logtoboth "> Plugin $pfx: Process filelist '$filelist'"
	    cp $filelist $assetdir/filelist-$(basename $filelist)
	    # read the file and add each specified file to the list
	    while read line
	    do
		unset mkdirif
		from="" ; to="" ; chown="" ; chmod=""
		plugin_getargs $pfx "$line" "$vldargs" "|from|to|"
		if [ "$runphase" != "" ]
		then
		    runphase="${runphase,,}"
		    if ! [[ "|phase1|postinstall|" =~ "$runphase" ]]
		    then
			logtoboth "% Unrecognized 'runphase' value '$runphase'; assuming 'phase1'"
			runphase="phase1"
		    fi
		fi
		[ -v mkdirif ] && mkdirif="yes"
		p0copyfile "$from" "$to" "$chown" "$chmod" "$mkdirif" $runphase
	    done < $filelist
	else
	    logtobothex "? Plugin $pfx: File for filelist '$filelist' not found"
	fi
    fi
    logtoboth "* Plugin $pfx: Complete Phase 0"

elif [ "$phase" == "1" ]
then
    #
    # Phase 1 (in nspawn)
    #
    logtoboth "* Plugin $pfx: Start Phase 1"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    #logfreespace "at start of Plugin $pfx Phase 1"
    #
    if compgen -G "$assetdir/run-phase1-*" >/dev/null
    then
	for runf in $assetdir/run-phase1-*
	do
	    logtoboth "> Plugin $pfx: Run $runf"
	    $runf || exit 1
	done
    fi
    #
    #logfreespace "at end of $pfx Phase 1"
    logtoboth "* Plugin $pfx: Complete Phase 1"
else
    #
    # Plugin Post-install edits
    #
    logtoboth "* Plugin $pfx: Start Phase post-install"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    #logfreespace "at start of Plugin $pfx Phase post-install"
    #
    if compgen -G "$assetdir/run-postinstall-*" >/dev/null
    then
	for runf in $assetdir/run-postinstall-*
	do
	    logtoboth "> Plugin $pfx: Run $runf"
	    $runf || exit 1
	done
    fi
    #
    #logfreespace "at end of $pfx Custom Phase post-install"
    logtoboth "* Plugin $pfx: Complete Phase post-install"
fi
