#!/usr/pkg/bin/runawk

# Copyright (c) 2011 Aleksey Cheusov <vle@gmx.net>
# All rights reserved.
#
# See LICENSE file

#.begin-str help
# pkg_summary2build_deps - takes src_summary (-s), bin_summary (-b) and
# PAeNA (PKGPATH enriched + PKGNAME) dependency graph built on ALL
# packages from src_summary and bin_summary using
# 'pkg_summary2deps -Apnrsal2'.
# As a result it outputs PAeNA dependency graph in which leaf packages
# are packages from src_summary that need to be rebuild,
# dependencies -- either binary packages listed in bin_summary
# or source packages from src_summary.
#
# usage: pkg_summary2build_deps [OPTIONS] [PAeNA_deps_files...]
# OPTIONS:
#   -h                display this screen
#   =s <src_summary>  filename for source summary
#   =b <bin_summary>  filename for binary summary
#   =r <rebuild>      filename for packages to be built (result)
#   =m <mode>         mode of dependency graph generation
#                     0 - use package from pkgsrc tree
#                         if it was updated (the default)
#                     1 - use latest available binary
#                         if it satisfies DEPENDS and BUILD_DEPENDS
#.end-str

#env "LC_ALL=C"

#use "exitnow.awk"
#use "power_getopt.awk"
#use "xgetline.awk"
#use "psu_funcs.awk"
#use "tmpfile.awk"
#use "shquote.awk"
#use "xsystem.awk"
#use "xclose.awk"

BEGIN {
	if (getarg("h")){
		print_help()
		exitnow(0)
	}

	bin_summary_fn = getarg("b")
	if (!bin_summary_fn){
		print "-b option is mandatory!" > "/dev/stderr"
		exitnow(1)
	}

	src_summary_fn = getarg("s")
	if (!src_summary_fn){
		print "-s option is mandatory!" > "/dev/stderr"
		exitnow(1)
	}

	rebuild_fn = getarg("r")

	mode = getarg("m", 0) + 0

	if (rebuild_fn)
		printf "" > rebuild_fn

	src_PAeNA_fn = tmpfile()
	printf "" > src_PAeNA_fn

	alldeps_fn = tmpfile()
	printf "" > alldeps_fn
}

function read_summary (fn, hash,          fail){
	fail = 0
	while (xgetline0(fn)){
		if ($0 ~ /^PKGPATH=/)
			pkgpath = substr($0, 9)
		else if ($0 ~ /^PKGNAME=/)
			pkgname = substr($0, 9)
		else if ($0 ~ /^PKG_FAIL_REASON=/)
			fail = 1
		else if (NF == 0){
			hash [pkgpath ";" pkgname] = fail
			pkgname = pkgpath = ""
			fail = 0
		}
	}
	close(fn)
}

BEGIN {
	read_summary(src_summary_fn, src_PAeNA)
	read_summary(bin_summary_fn, bin_PANA)
}

function print_dep (dep_type, dep, pkg){
	if (pkg != ""){
		print dep_type, dep, pkg > alldeps_fn
		already_printed [dep] = already_printed [pkg] = 0
	}else if (! (dep in already_printed)){
		print dep > alldeps_fn
		already_printed [dep] = 0
	}
}

function PAeNA2PANA (pkg){
	sub(/:[^;]*/, "", pkg)
	return pkg
}

NF == 3 {
	cnt = split($2, arr, /[|]/)
	bin_dep = src_dep = ""

	# bin_dep - PAeNA present in bin_summary that satisfies dependency
	# src_dep - PAeNA absent  in bin_summary that satisfies dependency
	for (i=1; i <= cnt; ++i){
		dep = arr [i]

		if (PAeNA2PANA(dep) in bin_PANA){
			if (bin_dep in src_PAeNA){
				# even if version goes backward,
				# pkgsrc tree version is always preferred
				continue
			}

			if (!bin_dep || (dep in src_PAeNA) || pkgname_gt_pkgname(dep, bin_dep)){
				# 1) we find first suitable package
				# 2) new suitable package comes from pkgsrc tree
				# 3) new suitable package has greater version than older one
				bin_dep = dep
			}
		}else if (dep in src_PAeNA){
			if (!src_dep || !src_PAeNA [dep])
				src_dep = dep

			print_dep("", dep)
			updated_PAeNA [dep] = 2
		}
	}

	# if $3 in pkg_src_summary but not in pkg_all_summary...
	if (($3 in src_PAeNA) && !(PAeNA2PANA($3) in bin_PANA))
		updated_PAeNA [$3] = 1

	if (src_dep && !src_PAeNA [src_dep])
		print_dep($1, src_dep, $3)
	else if (bin_dep)
		print_dep($1, bin_dep, $3)
	else if (src_dep)
		print_dep($1, src_dep, $3)
	else
		abort("Neither bin_dep nor src_dep are set")

	next
}

NF == 1 {
	if (($1 in src_PAeNA) && !(PAeNA2PANA($1) in bin_PANA))
		updated_PAeNA [$1] = 3
}

END {
	for (i in updated_PAeNA){
		print_dep("", i)
		if (rebuild_fn)
			print i > rebuild_fn
	}
	for (i in src_PAeNA){
		print i > src_PAeNA_fn
	}

	xclose(src_PAeNA_fn)
	xclose(alldeps_fn)
	if (rebuild_fn)
		xclose(rebuild_fn)

	cmd = "pkg_subgraph_deps -r -f " shquote(src_PAeNA_fn) " " shquote(alldeps_fn)
	xsystem(cmd)
}
