#!/usr/bin/perl

#- Copyright (C) 1999 MandrakeSoft (fpons@mandrakesoft.com)
#-
#- 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, or (at your option)
#- any later version.
#-
#- This program is distributed in the hope that it will be useful,
#- but WITHOUT ANY WARRANTY; without even the implied warranty of
#- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#- GNU General Public License for more details.
#-
#- You should have received a copy of the GNU General Public License
#- along with this program; if not, write to the Free Software
#- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

use strict qw(subs vars refs);
use rpmtools;

my $params = new rpmtools;
my ($noclean, $nohdlists, $nobasefiles, @root, @hdlists) = 0;

($noclean,     @ARGV) = @ARGV if $ARGV[0] eq "--noclean";
($nohdlists,   @ARGV) = @ARGV if $ARGV[0] eq "--nohdlists";
($nobasefiles, @ARGV) = @ARGV if $ARGV[0] eq "--nobasefiles";
(undef, @root, @ARGV) = @ARGV if $ARGV[0] eq "--distrib";

@root > 0 && @ARGV == 0 or die "usage: gendistrib [--noclean] [--nohdlists] [--nobasefiles] --distrib <root distrib> <root_distrib2> ...\n";

my $root = $root[0];
my ($depslist, $provides, $compss, $hdlists) = ("$root/ALTLinux/base/depslist.ordered",
						"$root/ALTLinux/base/provides",
						"$root/ALTLinux/base/compss",
						"$root/ALTLinux/base/hdlists");

#- try to read this one before! could be useful to sort hdlist building if the file exist and is up-to-date.
if (-r $depslist) {
    print STDERR "using existing $depslist file\n";
    open F, $depslist;
    $params->read_depslist(\*F);
    close F;
}

open F, $hdlists or die "unable to open $hdlists";
foreach (<F>) {
    chomp;
    s/\s*#.*$//;
    /^\s*$/ and next;
    m/^\s*(hdlist\S*\.cz2?)\s+(\S+)\s*(.*)$/ or die "invalid hdlist description \"$_\" in hdlists file";

    push @hdlists, [ "$root/ALTLinux/base/$1", $2, $3 ];
}
close F;

unless ($nohdlists) {
    for (0..$#hdlists) {
	my ($hdlist, $dir, $descr) = @{$hdlists[$_]};

	#- try to find the right repository where can be found the directory
	#- listed in the hdlist file.
	#- if the number of root is equal the number of medium, assume a medium
	#- foreach root, else try to find a valid root containing the medium.
	if (scalar(@hdlists ) == scalar(@root)) {
	    $root = $root[$_];
	} else {
	    foreach (@root) {
		-d "$_/$dir" and $root = $_, last;
	    }
	}
	-d "$root/$dir" or die "unable to find a valid root directory which contains $dir\n";

	print STDERR "building hdlist $hdlist as \"$descr\"\n  with rpms directory $root/$dir\n";
	$params->build_hdlist($noclean, 9, ($ENV{TMPDIR} || "/tmp") . "/.build_hdlist", $hdlist, glob("$root/$dir/*.rpm"));
    }
}

unless ($nobasefiles) {
    #- take a clean aproach.
    $params->clean();

    #- this version try to use an existing profiles file to reduce
    #- number of pass of parsing hdlist.
    if (-r $provides) {
	print STDERR "using existing $provides file\n";
	open F, $provides;
	$params->read_provides_files(\*F);
	close F;
    }

    #- now, try to build dependancy, but incrementally only.
    foreach (@hdlists) {
	print STDERR "reading $_->[0]\n";
	$params->read_hdlists($_->[0]);
	$params->compute_depslist();
    }

    my @unresolved = $params->get_unresolved_provides_files();
    if (@unresolved > 0) {
	foreach (@unresolved) {
	    print STDERR "found requires on file not yet found [$_], forcing two other linked pass\n";
	}

	#- cleaning.
	$params->clean();

	#- compute (avoiding depslist computation on first one.
	foreach (@hdlists) {
	    print STDERR "reading (second pass) $_->[0]\n";
	    $params->read_hdlists($_->[0]);
	}
	$params->keep_only_cleaned_provides_files();
	foreach (@hdlists) {
	    print STDERR "reading (third pass) $_->[0]\n";
	    $params->read_hdlists($_->[0]);
	    $params->compute_depslist();
	}
    }

    #- work finished, so write results:
    #-   $output_dir/depslist.ordered
    #-   $output_dir/provides
    #-   $output_dir/compss
    print STDERR "writing $depslist\n";
    open F, ">$depslist" or die "unable to write depslist file $depslist\n";
    $params->write_depslist(\*F);
    close F;
    print STDERR "writing $provides\n";
    open F, ">$provides" or die "unable to write provides file $provides\n";
    $params->write_provides(\*F);
    close F;
    print STDERR "writing $compss\n";
    open F, ">$compss" or die "unable to write compss file $compss";
    $params->write_compss(\*F);
    close F;
} else {
    if (-r $provides) {
	print STDERR "using existing $provides file\n";
	open F, $provides;
	$params->read_provides(\*F);
	close F;
    }
}

#- check if there are NOTFOUND in dependancy, check if they are in other medium, warn the user.
foreach my $pkg (@{$params->{depslist}}) {
    foreach (split " ", $pkg->{deps}) {
	/NOTFOUND_(.*)/ or next;
	print STDERR "$pkg->{name}-$pkg->{version}-$pkg->{release} require [$1] which\n";
	if ($params->{provides}{$1}) {
	    print STDERR "  is available on packages not listed in this medium or previous medium:\n";
	    foreach (@{$params->{provides}{$1}}) {
		print STDERR "    $params->{info}{$_}{name}-$params->{info}{$_}{version}-$params->{info}{$_}{release}\n";
	    }
	} else {
	    print STDERR "  is not available in any medium listed\n";
	    if (/NOTFOUND_(.*?)(-\d+.*)?\.so\./) {
		my $libname = quotemeta $1;
		foreach (keys %{$params->{provides}}) {
		    /$libname [\.-]/x or next;
		    print STDERR "  but a similar provides is available as [$_], need rebuild ?\n";
		}
	    }
	}
    }
}
