#!/usr/bin/perl
#
# warly <warly@mandrakesoft.com>
#
# modified by Stew Benedict <sbenedict@mandrakesoft.com>
#
my $version = "0.2.4-PPC";

use strict;

my ($rep,$iso) = @ARGV;
$iso or usage();
$::rep = $rep;
$::ENV{PATH} = "$rep/misc:$ENV{PATH}";
$::ENV{PERLLIB} = "$rep/misc:$ENV{PERLLIB}";
unshift @::INC, "$rep/misc";

require "$rep/misc/rpmtools.pm";

my $pwd = `pwd`;
chop $pwd;
$iso =~ s/^([^\/])/$pwd\/$1/;

my $arch = `uname -m`;
chop $arch;

if ($arch =~ /ppc/) {
	my $hfsutils = system("rpm -q hfsutils");
	die("Can't run without hfsutils!") if $hfsutils = '';
}

my $suffix = 'i586';
$suffix = 'PPC' if $arch =~ /ppc/;
	
my $tmpdir = $ENV{TMPDIR} || "/tmp";
-d $tmpdir or die "$tmpdir does not exist\n";
my $work_dir = "$tmpdir/.build_hdlist";
-d $work_dir or mkdir "$tmpdir/.build_hdlist";

my @cd;
open A, "$rep/Mandrake/base/rpmslist";
my ($num,@a);
my %list;
while(<A>){
	/<\/CD>/ and $num = 0;
	/<CD num=(\d+)>/ and do { $num = $1; push @cd, $num};
#	s/\+/\\\+/g;
	/(?:<.*>)*([^<]*)\n/; 
	$1 and do {
		@a = split ' ', $1;
		@list{@a} = map $num,@a;
	}
}

my @rpms;
my %name;
my $dir = "$rep/Mandrake/RPMS";
opendir DIR, $dir or die "unable to opendir $dir: !$\n";
foreach (readdir DIR) {
	my ($key, $name) = /(([^\/]*)-[^-]*-[^-]*\.[^\/\.]*)\.rpm$/ or next;
    	$name{$name} and next;
	my $n = $list{$name};
	push @{$rpms[$n]}, "$rep/Mandrake/RPMS/$_";
	$name{$name} = 1;
}

#goto TOTO;

open C, ">$work_dir/hdlists" or die "Could not open $work_dir/hdlists for writing: $!";
my $params = new rpmtools();
my @hdlist;
foreach my $n (@cd){
	print C "hdlist$n.cz Mandrake/RPMS$n CD $n Cooker\n";
	my $hdlist = "$work_dir/hdlist$n.cz";
	$hdlist[$n] = $hdlist;
	$params->build_hdlist(1,9,$work_dir,"$work_dir/hdlist$n.cz",@{$rpms[$n]})
}
close C;
foreach my $n (@cd){
	$params->read_hdlists($hdlist[$n]);
	$params->compute_depslist();
}

my @unresolved = $params->get_unresolved_provides_files();
if (@unresolved > 0) {
	$params->clean();

	foreach my $n (@cd){
		$params->read_hdlists($hdlist[$n]);
	}
	$params->keep_only_cleaned_provides_files();
	foreach my $n (@cd){
		$params->read_hdlists($hdlist[$n]);
		$params->compute_depslist();
	}
}
print "writing $work_dir/depslist.ordered\n";
open F, ">$work_dir/depslist.ordered" or die "unable to write depslist file $work_dir/depslist.ordered\n";
$params->write_depslist(\*F);
close F;
print "writing $work_dir/provides\n";
open F, ">$work_dir/provides" or die "unable to write provides file $work_dir/provides\n";
$params->write_provides(\*F);
close F;
print "writing $work_dir/compss\n";
open F, ">$work_dir/compss" or die "unable to write compss file $work_dir/compss";
$params->write_compss(\*F);
close F;
foreach my $n (@cd){
	$params->build_hdlist(1,9,$work_dir,"$work_dir/hdlist$n.cz",@{$rpms[$n]})
}

#TOTO:

my $mkiso = '';
if ($arch =~ /ppc/) {
    $mkiso = qq{$pwd/tools/ppc/mkhybrid-1.12b5.4 -part -hfs -r -l -J \\
	-V "Cooker_CD_1" \\
	-A "Mandrake_Linux" -P "MandrakeSoft" -abstract "README" \\
	-sysid "PPC" -volset "Update" -volset-size 2 -volset-seqno 1 \\
	-hfs-volid "Mandrake_Linux" \\
	-map $pwd/tools/ppc/mapping \\
	-magic $pwd/tools/ppc/magic -m "*.orig" \\
	-hide '*.MacOS' -hide '*.DOS' \\
	-hide-joliet '*.Unix' -hide-joliet '*.MacOS' \\
	-hide-hfs '*.Unix' -hide-hfs '*.DOS' -pad \\
	-o "$iso/1-Cooker-$suffix.iso" \\
	Mandrake/base/=$work_dir/compss				\\
        Mandrake/base/=$work_dir/depslist.ordered		\\
	Mandrake/base/=$work_dir/provides			\\
        Mandrake/base/=$work_dir/hdlists};
} else {
    $mkiso = qq{mkisofs -r -J -graft-points -nobak -V "Cooker_CD_1" -b images/cdrom.img -c images/boot.cat -o "$iso/1-Cooker-$suffix.iso" \\
	Mandrake/base/=$work_dir/compss				\\
        Mandrake/base/=$work_dir/depslist.ordered		\\
	Mandrake/base/=$work_dir/provides			\\
        Mandrake/base/=$work_dir/hdlists};
}

local *A; opendir A, "$rep";
foreach (readdir A){
	/~$/ and next;
	/^(\.{1,2}|Mandrake)$/ and next;
	-d "$rep/$_" and $mkiso .= "\\\n	/$_/=$rep/$_" and next;
	$mkiso .= "\\\n	/=$rep/$_" 
}

local *A; opendir A, "$rep/Mandrake";
foreach (readdir A){
	print "Mandrake -- $_\n";
	/~$/ and next;
	/(^(\.{1,2}|base)$|RPMS)/ and next;
	-d "$rep/Mandrake/$_" and $mkiso .= "\\\n	Mandrake/$_/=$rep/Mandrake/$_" and next;
	$mkiso .= "\\\n	Mandrake/=$rep/Mandrake/$_"
}

local *A; opendir A, "$rep/Mandrake/base";
foreach (readdir A){
	/~$/ and next;
	/(^(\.{1,2}|compss|provides|depslist.ordered)$|hdlist|cooker)/ and next;
	-d "$rep/Mandrake/base/$_" and $mkiso .= "\\\n	Mandrake/base/$_/=$rep/Mandrake/base/$_" and next;
	$mkiso .= "\\\n	Mandrake/base/=$rep/Mandrake/base/$_"
}

#print "$mkiso\n";
#exit;

foreach (@cd) {
	$mkiso .= "\\\n	Mandrake/base/=$work_dir/hdlist$_.cz"
}

foreach (@{$rpms[1]}){
	$mkiso .= "\\\n Mandrake/RPMS1/=$_" 
}

#print "$mkiso\n"; 
#exit;
system $mkiso;

if ($arch =~ /ppc/) {
 	#Bless boot folder on CD1 so yaboot can boot
	system("hmount $iso/1-Cooker-$suffix.iso");
	system("hattrib -b boot");
	system("hcd boot");
	system("hattrib -t tbxi -c UNIX ofboot.b");
	system("hattrib -t boot -c UNIX vmlinux");
	system("hattrib -t boot -c UNIX vmlinux-2.2");
	system("hattrib -t boot -c UNIX yaboot");
	system("hattrib -t conf -c UNIX yaboot.conf");
	system("humount");
}

foreach my $n (@cd){
	$n == 1 and next;
	$mkiso = qq{mkisofs -r -J -graft-points -nobak -V "Cooker_CD_$n" -o "$iso/$n-Cooker-$suffix.iso"}; 
	foreach (@{$rpms[$n]}){
		$mkiso .= "\\\n Mandrake/RPMS$n/=$_"
	}
	#- on PPC, discard anything not on the list
	if ($arch !~ /ppc/) {
	    $n == @cd and do { foreach (@{$rpms[0]}){
		$mkiso .= "\\\n Mandrake/RPMS$n/=$_"	
	    }};
	}
	#	print "$mkiso\n";
	system $mkiso;
}

# system("rm -rf $work_dir");

foreach (@{$rpms[0]}){
    if ($arch =~ /ppc/) {
	print "WARNING: $_ not in lists, discarded!\n"
    } else {
	print "WARNING: $_ not in lists, added to last CD\n"
    }
}

exit;

sub usage{
	print "mkcd.pl version $version
	usage:
	$0 <repository dir> <iso creation dir>\n";
	exit
}
