#!/usr/bin/perl

=pod

=head1 Name

emprunecross - Identify cross dependencies installed by dpkg-cross

=head1 Copyright and Licence

 Copyright (C) 2007  Neil Williams <codehelp@debian.org>

 This package 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.

=cut

use File::Basename;
use Debian::DpkgCross;
use Term::ANSIColor qw(:constants);
use strict;
use warnings;
use vars qw/ $arch %chain %prune $target_gnu_type $suite $list $status
$success @cross %chain $crosslist $progname $string $cmd $dryrun
$our_version $unpacked /;

$dryrun = 0;
$progname = basename($0);
$our_version = &script_version();
$suite = "unstable";
&read_config();
$arch = &get_architecture();
sub usageversion {
    print(STDERR <<END)
$progname version $our_version

Usage:
 $progname [-n|--dry-run|--simulate] [-a|--arch ARCH]
 $progname -?|-h|--help|--version

Options:
 -n|--dry-run|--simulate:     Do a dry-run, do not change anything.
 -a|--arch ARCH:              Set architecture (default: defined by dpkg-cross)
 -s|--suite SUITE:            set the suite.

 -?|-h|--help:       Print this usage message and exit
 --version:          Print this usage message and exit

END
        || die "$0: failed to write usage: $!\n";
exit 0;
}

while( @ARGV ) {
	$_= shift( @ARGV );
	last if m/^--$/;
	if (!/^-/) {
		unshift(@ARGV,$_);
		last;
	}
	elsif (/^(-\?|-h|--help|--version)$/) {
		&usageversion();
		exit( 0 );
	}
	elsif (/^(-n|--dry-run|--simulate)$/) {
		$dryrun++;
	}
	elsif (/^(-s|--suite)$/) {
		$suite = shift;
	}
	elsif (/^(-a|--arch)$/) {
		$arch = shift(@ARGV);
	}
	else {
		die RED, "$progname: Unknown option $_.", RESET, "\n";
	}
}

$target_gnu_type = &check_arch($arch);
die (RED, "\n$progname: Cannot determine the architecture to check.", RESET, "\n\n")
	if ((not defined $arch)||($arch eq "")||(not defined $target_gnu_type));

$suite = &get_targetsuite;
$list = &prepare_checklist($arch, $target_gnu_type);
$status = 'install ok installed';
$unpacked = 'install ok unpacked';
$success = "";
$string = " ";
%chain=();
foreach my $res (sort @$list)
{
	$success = `dpkg-query -W -f='\${Package} \${Status}' $res 2>/dev/null`;
	$string = "$res $status";
	$chain{$res}++ if ($success eq $string);
}

$crosslist = `dpkg-query -W -f='\${Package} \${Status}\n' \'*-$arch-cross\'`;
@cross = split(/\n/, $crosslist);

foreach my $c (@cross)
{
	next if (($c !~ / $status$/) and ($c !~ / $unpacked/));
	$c =~ s/ $status$//;
	$c =~ s/ $unpacked//;
	chomp($c);
	next if (defined $chain{$c});
	next if ($c =~ /^libc6.*$arch-cross/);
	$prune{$c}++;
}
if (scalar keys %prune > 0)
{
	my $plural = (scalar keys %prune == 1) ? "package" : "packages";
	print RED, "Removing $plural\n", RESET;
	if ($dryrun > 0)
	{
		$cmd = join("\n", sort keys %prune);
		print "$cmd\n";
		exit(0);
	}
	$cmd = join(" ", sort keys %prune);
	system ("sudo dpkg -P $cmd");
}

exit 0;

sub script_version {
	my $query = `dpkg-query -W -f='\${Version}' emdebian-crush`;
	(defined $query) ? return $query : return "2.2.3";
}

sub prepare_checklist
{
	my $arch = shift;
	my $target_gnu_type = shift;
	push my @list ,"binutils-${target_gnu_type}";
	push @list, "${gcc_vers}-${target_gnu_type}-base";
	push @list, "${gcc_vers}-${target_gnu_type}";
	push @list, "cpp-${gcc_latest}-${target_gnu_type}";
	push @list, "g++-${gcc_latest}-${target_gnu_type}";
	push @list, "${libc_vers}-${arch}-cross";
	push @list, "${libc_vers}-dev-${arch}-cross";
	push @list, "libstdc++${libc_latest}-${arch}-cross";
	push @list, "libstdc++${libc_latest}-${gcc_latest}-dev-${arch}-cross";
	push @list, "libstdc++${libc_latest}-${gcc_latest}-pic-${arch}-cross";
	push @list, "libgcc1-${arch}-cross";
	push @list, &check_linux($arch);
	my $multilib;
	my $our_arch = `dpkg-architecture -qDEB_BUILD_ARCH`;
	chomp ($our_arch);
	$multilib = "libc6-dev-i386" if ($our_arch =~ /^amd64$/);
	push @list, $multilib if (defined $multilib);
	return \@list;
}

sub check_linux
{
	my $arch = $_[0];
	my $query = `dpkg-query -W -f=' \${Package} \${Status}' linux-kernel-headers 2>/dev/null`;
	return "linux-kernel-headers-${arch}-cross"
		if ($query eq " linux-kernel-headers install ok installed");
	return "linux-libc-dev-${arch}-cross";
}

=head1 Description

Removes or just prints the complete list of packages that have been
installed by dpkg-cross (whether using dpkg-cross directly or via
apt-cross or emdebian-tools) for the selected architecture or dpkg-cross
default architecture.

This functionality cannot just be merged into apt-cross because that would
remove cross packages used by the Emdebian toolchain.


=head1 Commands and options

 -a|--arch
Override the dpkg-cross default architecture.

 -n|--dry-run|--simulate
Only print the list, do not call 'sudo dpkg -P'

=cut
