#!/usr/pkg/bin/runawk

# Copyright (c) 2010-2015, Aleksey Cheusov <vle@gmx.net>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#use "exitnow.awk"
#use "power_getopt.awk"
#use "trim.awk"
#use "tmpfile.awk"
#use "has_prefix.awk"
#use "xsystem.awk"

#.begin-str help
# XB2bin_summary - converts output of 'pkg_info -XB' to bin_summary
# Usage: XB2bin_summary [OPTIONS] [files...]
# OPTIONS:
#  -h                display this help
#  =a <fields>       add specified fields to the output
#  =f <fields>       output only specified fields
#  =r <fields>       remove specified fields
#.end-str

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

	add_fields_str=getarg("a")
	gsub(/,/, " ", add_fields_str)
	cnt=split(add_fields_str, arr)
	for (i=1; i <= cnt; ++i)
		add_fields [arr [i]] = 1

	rem_fields_str=getarg("r")
	gsub(/,/, " ", rem_fields_str)
	cnt=split(rem_fields_str, arr)
	for (i=1; i <= cnt; ++i)
		rem_fields [arr [i]] = 1

	only_fields_str=getarg("f")
	gsub(/,/, " ", only_fields_str)
	cnt=split(only_fields_str, arr)
	for (i=1; i <= cnt; ++i)
		only_fields [arr [i]] = 1

	multiline ["PLIST"]       = 1
	multiline ["DESCRIPTION"] = 1
	multiline ["DEPENDS"]     = 1
	multiline ["REQUIRES"]    = 1
	multiline ["PROVIDES"]    = 1
	multiline ["CONFLICTS"]   = 1

	#
	need_assigns = ("ASSIGNMENTS" in only_fields) || ("ASSIGNMENTS" in add_fields)
	need_reqd = ("REQUIREDBY" in only_fields) || ("REQUIREDBY" in add_fields)
	need_plist = ("PLIST" in only_fields) || ("PLIST" in add_fields)

	if (need_reqd){
		out_file = tmpfile()
		add_fields  ["PKGNAME"] = 1
		only_fields ["PKGNAME"] = 1
	}

	#
	X_section = 1
	L_section = 0

	pkg_info_cmd="/usr/sbin/pkg_info -K /usr/pkg/pkgdb"
}

NF == 0 {
	prev_is_empty = 1
	next
}

($1 == "Build" || $1 == "Installed") && $2 == "information:" {
	prev_is_empty = 0
	X_section = 0
	L_section = 0
	next
}

$1 == "Files:" {
	prev_is_empty = 0
	X_section = 0
	L_section = 1
	next
}

function print_me (s){
	if (out_file)
		print s > out_file
	else
		print s
}

function eos (){
	# end of package summary
	if (need_assigns && assigns != ""){
		print_me("ASSIGNMENTS=" assigns)
	}

	print_me("")
	X_section = 1
	L_section = 0
	delete already_printed
	assigns = ""
}

prev_is_empty {
	eos()
}

L_section {
	print "PLIST=" $0
}

{
	eq_idx = index($0, "=")
	fname  = substr($0, 1, eq_idx-1)
	if (need_assigns && fname == "MULTI"){
		assigns = substr($0, eq_idx+1)
		gsub(/ /, ",", assigns)
	}

	# print current non-empty line
	if (rem_fields_str != "" && (fname in rem_fields))
		ok = 0
	else if (only_fields_str != "" && !(fname in only_fields))
		ok = 0
	else if (!X_section && ((fname in add_fields) || (fname in only_fields)))
		ok = 1
	else
		ok = X_section

	if (ok && !(fname in already_printed)){
		if (!(fname in multiline))
			already_printed [fname] = 1

		print_me($0)
	}

	# 
	prev_is_empty = 0
}

END {
	if (prev_is_empty)
		eos()

	if (!need_reqd)
		exitnow(0)

	##########################################################################
	### REQUIREDBY section

	# close file with bin_summaries
	printf "" > out_file
	xclose(out_file)

	# generating file with required_by information
	reqd_file = tmpfile()
	pipe = "xargs " pkg_info_cmd " -R > " reqd_file
	while(xgetline0(out_file)){
		if (has_prefix($0, "PKGNAME="))
			print substr($0, 9) | pipe
	}
	xclose(out_file)
	xclose(pipe)

	#
	while (xgetline0(reqd_file)){
		if ($1 == "Information" && $2 == "for"){
			pkgname = $3
			sub(/:$/, "", pkgname)
		}else if (NF == 1 && !index($0, ":")){
			reqd [pkgname, ++reqd_count [pkgname]] = $1
		}
	}
	xclose(reqd_file)

	#
	while (xgetline0(out_file)){
		print $0
		if (has_prefix($0, "PKGNAME=")){
			pkgname = substr($0, 9)
			for (i=1; i <= reqd_count [pkgname]; ++i){
				print "REQUIREDBY=" reqd [pkgname, i]
			}
		}
	}
}
