#!/bin/sh
#-*-mode:  sh -*-

# 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.

set -e

. pipestatus

export LC_ALL=C

LIBEXECDIR=${LIBEXECDIR-/usr/pkg/libexec/psu}
. ${LIBEXECDIR}/sig_handler.sh
on_exit () {
	# Stupid test for stupid Solaris :-/
	if test -n "$tmp_dir"; then rm -rf $tmp_dir; fi
}

usage () {
    cat 1>&2 <<EOF
pkg_digger_summary is a pkg summary searcher
(backend for pkg_digger).
usage: pkg_digger_summary -h
       pkg_digger_summary -f
       pkg_digger_summary -s
       pkg_digger_summary [-n limit] fsq1 [fsq2 ...]
       pkg_digger_summary -1|-3|-9|-i [-q] pkgid1 [pkgid2...]
where pkgid is <PKGPATH>,<PKGNAME>
and fsq is <field>:<strategy>:<query>
OPTIONS:
   -h         display this screen
   -s         display available search strategies
   -f         display available fields for search in
   -1         display 1-line information about packages
   -3         display short information about packages
   -9|-i      display full information about packages
   -q         quiet mode
   -n <limit>    maximum number of results
EOF
}

check_summary (){
    if test -z "$PKG_DIGGER_SUMMARY"; then
	echo 'PKG_DIGGER_SUMMARY environment variable must be set' 1>&2
	exit 1
    fi
}

if test $# -eq 0; then
    usage
    exit 2
fi

limit=1000000000

show_fields (){
    check_summary
    runawk -F= -f heapsort.awk -e '
	BEGIN {hash ["PKGBASE"] = hash ["PKGPATHe"] = ""
	       hash ["PKGPABA"] = hash ["PKGPANA"] = hash ["PKGPAIR"] = ""}
	NF > 0 {hash [$1]=0}
	END {cnt = heapsort_indices(hash, remap)
	     for (i=1; i <= cnt; ++i) {print remap [i]}}' \
	"$PKG_DIGGER_SUMMARY"
    exit 0
}

FIELDS_3='PKGNAME PKGPATH HOMEPAGE COMMENT MAINTAINER CATEGORIES DESCRIPTION'
FIELDS_9=''

while getopts hsf139iqn: f; do
    case "$f" in
	s)    pkg_grep_summary -T -T; exit 0;;
	f)    show_fields;;
	9|i)  stype=9; unset FIELDS || true;;
	3)    stype=3; FIELDS=-f`echo $FIELDS_3 | tr ' ' ,`;;
	1)    stype=1; unset FIELDS || true;;
	q)    quiet_mode=1;;
	n)    limit=$OPTARG;;
	h)    usage; exit 0;;
	?)    printf "Run pkg_digger_summary -h for details\n"; exit 2;;
    esac
done
shift `expr $OPTIND - 1`

check_summary

summary2onelineinfo (){
    runawk -v quiet_mode="$quiet_mode" -e \
	'/^(PKGNAME|PKGPATH|COMMENT)=/ || NF==0 {found=1; print}
	END {
	    if (!found){
		if (!quiet_mode)
		    print "No matches found" > "/dev/stderr"
		exit 20
	    }
	}' "$@"
}

case "$stype" in
    1)
	# -1
	pkg_grep_summary -r -fPKGNAME,PKGPATH,COMMENT -i \
	    -t strlist PKGPAIR "$*" < "$PKG_DIGGER_SUMMARY" |
	summary2onelineinfo

	exit 0;;
    3|9)
	# -3|-9
	if ! pkg_grep_summary $FIELDS -r -i -t strlist PKGPAIR "$*" \
	    < "$PKG_DIGGER_SUMMARY"
	then
	    exit 20
	fi

	exit 0;;
    *)
	# f:s:q
	tmp_dir=`mktemp -d ${TMPDIR-/tmp}/pkg_digger.XXXXXX`
	test -n $tmp_dir || exit 1

	cnt=1
	for i in "$@"; do
	    if printf '%s\n' "$i" | grep -q ':.*:'; then
		:
	    else
		echo "Invalid search pattern: '$i'," 1>&2
		echo "   field:strategy:query is expected" 1>&2
		exit 34
	    fi

	    field=`echo "$i" | cut -d: -f1`
	    strat=`echo "$i" | cut -d: -f2`
	    query=`echo "$i" | cut -d: -f3`
	    pkg_grep_summary -fPKGNAME,PKGPATH,ASSIGNMENTS -i \
		-t "$strat" "$field" "$query" < "$PKG_DIGGER_SUMMARY" > "$tmp_dir/$cnt" &
	    cnt=$(($cnt+1))
	done
	wait
	runawk -v quiet_mode="$quiet_mode" -v limit="$limit" \
	    -e '
	/^PKGPATH=/ {
	    pkgpath = substr($0, 9)
	    sub(/:.*/, "", pkgpath)
	    next
	}
	/^PKGNAME=/ {
	    pkgbase = substr($0, 9)
	    sub(/-[^-]*$/, "", pkgbase)
	    next
	}
	NF == 0 {
	    pkgpair = pkgpath "," pkgbase
	    if (pkgpair in hash)
		next
	    hash [pkgpair] = 1
	    print pkgpair
	    if (++matches == limit)
		exit 0
	}
	END {
	    if (!matches){
		if (!quiet_mode)
		    print "No matches found" > "/dev/stderr"
		exit 20
	    }
	}' "$tmp_dir"/*
	exit 0;;
esac
