#!/bin/sh
#
# repo-cooking - SliTaz cook: make repo.json.gz for Repology.
#
# packages.info is a flat list of binary packages, Repology wants them
# grouped by source. Join it with the wok: one item per receipt ("meta",
# source data) holding the packages it builds ("pkgs": main + SPLIT).
# Only packages present in packages.info are listed. Read by Repology's
# SliTazJsonParser. Based on repo-cooking by Aleksej Bobylev (2018-2019).
#
# Usage: repo-cooking [<packages-dir>]   # default: $PKGS
#
# Copyright (C) SliTaz GNU/Linux - GNU GPL v3
#

. /usr/lib/slitaz/libcook.sh

[ -n "$1" ] && PKGS="$1"
pi="$PKGS/packages.info"
if [ ! -s "$pi" ] || [ ! -d "$WOK" ]; then
	_ 'No packages.info in "%s" or no wok in "%s"' "$PKGS" "$WOK"
	exit 1
fi

tmp=$(mktemp -d)


# Pass 1, the wok: one "M" line per receipt (source data) followed by
# one "P" line per package name it builds.

cd $WOK
for pkg in *; do
	case $pkg in
		# SliTaz wrappers and translations: no upstream to compare
		get-*|locale-*) continue ;;
	esac
	[ -s "$WOK/$pkg/receipt" ] || continue
	sh -n "$WOK/$pkg/receipt" 2>/dev/null || continue
	unset PACKAGE VERSION MAINTAINER LICENSE WEB_SITE WGET_URL SPLIT
	. $WOK/$pkg/receipt
	[ -n "$VERSION" ] || continue

	m=${MAINTAINER##*<}; m=${m%%>*}
	# first URL only, VCS prefixes as plain schemes (git|https://... -> git://...)
	src=$(echo $WGET_URL | sed 's| .*||; s#^git|git#git#; s#^git|https*#git#;
		s#^svn|https*#svn#; s#^subversion|svn#svn#; s#^subversion|https*#svn#;
		s#^svn|svn#svn#; s#^hg|#hg://#; s#^mercurial|#hg://#;
		s#^bzr|#bzr://#; s#^cvs|#cvs://#')
	printf 'M\t%s\t%s\t%s\t%s\t%s\t%s\n' "$PACKAGE" "$VERSION" "$m" \
		"$(echo $LICENSE)" "$WEB_SITE" "$src"
	for name in $PACKAGE $SPLIT; do
		echo "P	$PACKAGE	${name%%:*}"
	done
done > $tmp/wok.tsv


# Pass 2, join with packages.info and write the JSON.
# packages.info: 1 name, 2 version, 3 category, 4 short desc, 11 arch
# code (6 = $ARCH, 0 = any; absent on i486, see bin/cook)

awk -F'\t' -v repo="SliTaz Cooking $ARCH" -v arch="$ARCH" \
	-v date="$(date -u '+%F %T')" '
function q(s) {
	gsub(/\\/, "\\\\", s); gsub(/"/, "\\\"", s); gsub(/[\001-\037]/, " ", s)
	return "\"" s "\""
}
function list(s,    n, a, i, r) {
	n = split(s, a, " ")
	for (i = 1; i <= n; i++) r = r (i > 1 ? "," : "") q(a[i])
	return "[" r "]"
}
function flush() {
	if (meta == "" || pkgs == "") return
	printf "%s{\"meta\":%s,\"ver\":%s,\"maintainer\":%s,\"license\":%s,\"home\":%s",
		items++ ? ",\n" : "", q(meta), q(ver), q(maint),
		list(lic == "" ? "unknown" : lic), q(home)
	if (src != "") printf ",\"src\":%s", q(src)
	printf ",\"pkgs\":[%s]}", pkgs
}
FNR == NR {
	a = $11 == "0" ? "any" : arch
	info[$1] = "{\"name\":" q($1) ",\"ver\":" q($2) ",\"cat\":" q($3) \
		",\"desc\":" q($4) ",\"arch\":" q(a) "}"
	next
}
$1 == "M" {
	flush()
	meta = $2; ver = $3; maint = $4; lic = $5; home = $6; src = $7
	pkgs = ""; delete seen
	next
}
$1 == "P" && ($3 in info) && !($3 in seen) {
	seen[$3] = 1
	pkgs = pkgs (pkgs == "" ? "" : ",") info[$3]
}
BEGIN { printf "{\"repo\":%s,\"date\":%s,\"items\":[\n", q(repo), q(date) }
END { flush(); print "\n]}" }
' $pi $tmp/wok.tsv > $tmp/repo.json

items=$(grep -c '"meta"' $tmp/repo.json)
if [ "$items" -gt 0 ]; then
	gzip -9 $tmp/repo.json
	mv -f $tmp/repo.json.gz $PKGS/repo.json.gz
	_ 'Repology: %s source packages in %s' "$items" "$PKGS/repo.json.gz"
else
	_ 'Repology: empty repo.json, %s kept as is' "$PKGS/repo.json.gz"
fi
rm -rf $tmp
