###
# Fatdog Builder function library
# Copyright (C) James Budiono, 2013, 2014, 2015
# License: GNU GPL Version 3 or later
#
# this file is sourced, not run.
#

type mawk >/dev/null && AWK=mawk || AWK=awk

### parse package name (any variant) and returns completed PKG* name components
### Only $1 is needed, $2,$3,$4 are defaults
# in: $1-PKG (any variant), default: $2-PKGVER $3-PKGARCH $4-PKGBUILD
# out: PKGBUILD PKGVER PKGARCH PKGNAME (all components never empty)
get_pkgname() {
	local p1=$1 p2=${2:-1.0} p3=${3:-$DEF_PKGARCH} p4=${4:-1}
	#echo $p1 $p2 $p3 $p4
	eval $($AWK -vp1=$p1 -vp2=$p2 -vp3=$p3 -vp4=$p4 \
	'BEGIN { # awk is a faster string processor than shell
		len = split(p1,comp,"-")
		for (i=1; i<=len; i++) rcomp[len-i]=comp[i]; # reverse, change to 0-based
		
		ind=0;
		# last component is a number with a dot, assume version
		if (rcomp[0] ~ /^[0-9]+\./) {
			pkgbuild=p4; pkgarch=p3; pkgver=rcomp[ind++];
		} else {
			# last component is a number without a dot, assume build number
			if (rcomp[0] ~ /^[0-9]+/ && len >=4 ) {
				pkgbuild=rcomp[ind++]; pkgarch=rcomp[ind++]; pkgver=rcomp[ind++];
			} else {
				if (rcomp[1] ~ /^[0-9]+/) {
					pkgbuild=p4; pkgarch=rcomp[ind++]; pkgver=rcomp[ind++]; 
				} else {
					if (rcomp[2] ~ /^[0-9]+/) {
						pkgbuild=rcomp[ind++]; pkgarch=rcomp[ind++]; pkgver=rcomp[ind++];
					} else {
						pkgbuild=p4; pkgarch=p3; pkgver=p2;
					}				
				}
			}
		}
		for (i=ind; i<len; i++) {
			pkgname=rcomp[i] "-" pkgname
		}
		pkgname=substr(pkgname,1,length(pkgname)-1)
		printf("PKGNAME=%s PKGVER=%s PKGARCH=%s PKGBUILD=%s\n",pkgname,pkgver,pkgarch,pkgbuild)
	}')
	#echo get_pkgname $PKGNAME---$PKGVER---$PKGARCH---$PKGBUILD
}

###
# input: stdin - list of files, $PKGNAME, $PKGVER, $PKGARCH, $PKGBUILD
# output: stdout - full path of pkg, if exist
awk_find_pkg() {
	$AWK -vp0=$PKGNAME -vp1=-$PKGVER -vp2=-$PKGARCH -vp3=-$PKGBUILD \
	'function basename(v) {
		sub(/.*\//,"",v); return v
	}
	function fexist(f,  v,n) {
		n=(getline v < f)
		close(f)
		return (n >= 0)
	}
	BEGIN { count=0 }
	{ files[count]=$0; names[count]=basename($0); count++ }
	END {
		if (count==1) { print files[0]; exit; } # short-circuit for easy stuff
		part[pmax++]=p0; part[pmax++]=p1; part[pmax++]=p2; part[pmax++]=p3; part[pmax++]=p4;
		keep_pmax = pmax
		attempt = 2	
		strict = 1 # exact match
		while (attempt) {
			attempt--
			pmax = keep_pmax
			while (pmax>1) {
				pkgname=""; pmax--
				for (i=0; i<pmax; i++) pkgname=pkgname part[i]
				pkgname = pkgname
				#print "checking " pkgname
				for (i=0; i<count; i++) {
					if ( (strict && names[i] == pkgname) ||
					     (!strict && index(names[i], pkgname)) ) 
					{
						if (fexist(files[i] "/recipe")) {
							print files[i]
							exit
						}
					}
				}
			}
			strict = 0 # now allow partial match
		}
	}'
}


### find a package, load its recipe, and returns complete PKG* name components.
# in: $1-PKG_DIR, $2-PKG (any variant), $3-cache, $4-maxdepth (default 5)
# out: PKG PKGNAME PKGVER PKGARCH PKGBUILD PKG_FULL_PATH
# uses: get_pkgname, awk_find_pkg
find_pkg() {
	[ -z "$2" ] && echo Please specify package to build. && return 1
	get_pkgname "$2" # returns parameter for use by awk_find_pkg
	if [ "$3" ]; then
		PKG_FULL_PATH=$(grep -F "/$PKGNAME" "$3" | awk_find_pkg)
	else
		PKG_FULL_PATH=$(find "$1" -maxdepth ${4:-5} -type d -name "$PKGNAME*" | sort | awk_find_pkg)
	fi
	#return
	[ -z "$PKG_FULL_PATH" ] && echo Cannot find package $2 && return 1
	. $PKG_FULL_PATH/recipe # may update PKG* components
	
	# normalise package names
	PKGNAME=${PKG_FULL_PATH##*/}
	get_pkgname $PKGNAME $PKGVER $PKGARCH $PKGBUILD
	PKG=$PKGNAME-$PKGVER-$PKGARCH-$PKGBUILD
	#echo $PKG $PKG_FULL_PATH
}

### cache helper
# $1-PKG_DIR, $2-depth (default 5)
# out: stdout - cache filename
create_find_pkg_cache() {
	local cache=/tmp/findpkg.$$
	find "$1" -maxdepth ${2:-5} -type d > $cache
	echo $cache	
}
