#!/bin/bash
#
# --- ROCK-COPYRIGHT-NOTE-BEGIN ---
# 
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
# Please add additional copyright information _after_ the line containing
# the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
# the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
# 
# ROCK Linux: rock-src/scripts/Create-DepDB
# ROCK Linux is Copyright (C) 1998 - 2005 Clifford Wolf
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. A copy of the GNU General Public
# License can be found at Documentation/COPYING.
# 
# Many people helped and are helping developing ROCK Linux. Please
# have a look at http://www.rocklinux.org/ and the Documentation/TEAM
# file for details.
# 
# --- ROCK-COPYRIGHT-NOTE-END ---

cachedir="package"
descdir="package"
debug=''

while [ "$1" ] ; do
	case "$1" in
	    -cachedir)
		cachedir=$2 ; shift ; shift ;;
	    -descdir)
		descdir=$2  ; shift ; shift ;;
	    -debug)
		debug=$2    ; shift ; shift ;;
	    *)
		echo
		echo "Usage: $0 [ -cachedir cachedir ] [ -descdir descdir ] \\"
		echo "       ${0//?/ } [ -debug pkg ] > filename"
		echo
		echo "	This scripts creates the scripts/dep_db.txt file from"
		echo "	the *.cache and *.desc files."
		echo
		exit 1 ;;
	esac
done

echo "Reading *.cache and *.desc files ..." >&2

perl1="" perl2=""
while read package command group packages
do
	package=${package%.desc:*}
	package=${package##*/}

	for p in $package $packages; do
		perl1="$perl1 \$deps{'$group'} = 1 if defined \$deps{'$p'};"
		perl2="$perl2 \$deps{'$p'} = 1 if defined \$deps{'$group'};"
	done
done < <( egrep '^\[(E|DEP|DEPENDENCY)\][ 	]+group[ 	]' $descdir/*/*/*.desc )

perl -e '

	my %deldeps = ();
	my %adddeps = ();

#	open(F, "scripts/dep_fixes.txt") or die $!;
#	while (<F>) {
#		chomp;
#		if (/^([^#\s]\S*)\s+del\s+(.*)$/) {
#			my ($p, $l) = ($1, $2);
#			$deldeps{$p}{$_} = 1 foreach (split /\s+/, $l);
#			next;
#		}
#		if (/^([^#\s]\S*)\s+add\s+(.*)$/) {
#			my ($p, $l) = ($1, $2);
#			$adddeps{$p}{$_} = 1 foreach (split /\s+/, $l);
#			next;
#		}
#	}
#	close F;

	foreach my $c (<'$cachedir'/*/*/*.cache>) {
		my ($pri, $time) = (1, 1);
		my $pkg = $c; $pkg=~s,^.*/([^/]*)\.cache$,$1,; 
		my $found_dep_entries = 0;
		my %deps = ();
		my $d = $c;

		$d =~ s,([^/]*)/[^/]*\.cache$,$1/$1.desc,;
		$d =~ s,^'$cachedir','$descdir',;
		if ( ! -f $d ) {
			print STDERR "WARNING: Can'\''t find $d -> skipping $c.\n";
			next;
		}

		$deps{$_} = 1 foreach (keys %{$adddeps{$pkg}});

		open(F, "$c") or die "$!: $c";
		while (<F>) {
			if (/^\[BUILDTIME\]/) {
				@_ = split /\s+/;
				$time = $_[1];
				next;
			}
			if (/^\[DEP\]/) {
				@_ = split /:\S+\s+|\s+/; shift @_;
				foreach (@_) { $deps{$_} = 1 unless defined $deldeps{$pkg}{$_}; }
				$found_dep_entries = 1;
				next;
			}
		}
		close F;

		# no dep_db entry if this package failed in ref build
		next unless $found_dep_entries;

		open(F, "$d") or die "$!: $d";
		while (<F>) {
			if (/^\[(P|PRI|PRIORITY)\]/) {
				@_ = split /\s+/;
				$_[2] =~ s/^.*([0-8]).*$/$1/;
				$pri = $_[2].".".$_[3];
				next;
			}
		}
		close F;

		'"$perl1 $perl2"'

		print "$pkg $time $pri ", join(" ", sort keys %deps), " $pkg\n";
	}

' | gawk '

function getpri(package) {
	datafile="'$tmp1'";

	delete todo;
	delete done;
	todo[ package ] = 1;
	returncode=0;
	endloop=0;
	level=0;

	if (debug != "") {
		print "";
		print "Creating priority for " package " ...";
	}

	while ( ! endloop ) {
	    endloop=1; level++;
	    for (pkg in todo) {
		endloop=0;
		delete todo[pkg];
		done[pkg] = 1;
		firstdebug=1;

		for (nextpkg in database) {
		    if ( index(database[nextpkg], " " pkg " ") ) {
			if ( ! (nextpkg in done) &&
			     ! (nextpkg in todo) &&
			     ! (nextpkg in ignore) ) {
				if ("x" orderdb[nextpkg] < "x" orderdb[pkg]) {
				    if (debug != "") {
					if (firstdebug)
					    print "\n\t(" level ") Found " \
					          "dependencies for " pkg ":";
					print "\t\t" pkg ": " \
					      "required by " nextpkg \
					      " (ignore reverse dep)";
					firstdebug=0;
				    }
				} else {
				    if (debug != "") {
					if (firstdebug)
					    print "\n\t(" level ") Found " \
					          "dependencies for " pkg ":";
					print "\t\t" pkg ": " \
					      "required by " nextpkg;
					firstdebug=0;
				    }
				    todo[nextpkg] = 1;
				    returncode++;
				}
			}
		    }
		}
	    }
	}

	return returncode;
}

BEGIN {
	counter=0;
	debug="'$debug'";
}

{
	orderdb[$1]=$3; $3=0;
	database[$1]=$0;
	if (NF > 150) {
		printf "\rPackage %s has more then 150 (%d) dependencies. " \
		       "I do not believe this.\n", $1, NF - 3 > "/dev/stderr";
		ignore[$1] = 1;
	}
	counter++;
}

END {
	if (debug != "") {
		pri=getpri(debug);
		print "\nResulting Priority: " pri;
	} else {
		for (package in database) {
			printf "\rCreating dependency database (" \
			       counter ") ... \b" > "/dev/stderr";
			$0 = database[package];
			$3 = getpri(package);
			$1 = $1 ":"; print;
			counter--;
		}

		print "\rCreating dependency database ... " \
		      "done." > "/dev/stderr";
	}
}
' | if [ "$debug" ] ; then cat ; else sort ; fi