#!/usr/bin/perl

#  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.
#  
#  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., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#  

use strict;
use warnings;
use File::Basename;
use Cwd qw (realpath getcwd);
use vars qw / $progname $variant @lines $srcdir $rootdir $perlver @copying $arch 
 $ver %names $crossver $clean $perlver $usedevel /;
$progname = basename($0);
# expect to find the perl source code with Debian packaging in pwd
$srcdir = getcwd();
$rootdir = '/usr/share/perl-cross-debian/';
$ver = &our_version();
%names = ( static => 1, debug => 2, shared => 3, native => 4 );
while( @ARGV ) {
	$_= shift( @ARGV );
	last if m/^--$/;
	if (!/^-/) {
		unshift(@ARGV,$_);
		last;
	} elsif (/^(-\?|-h|--help|--version)$/) {
		&usageversion();
		exit( 0 );
	} elsif (/^(--rootdir)$/) {
		$rootdir = shift;
		$rootdir = `realpath $rootdir`;
		chomp ($rootdir);
		$rootdir .= '/';
	} elsif (/^(--variant)$/) {
		$variant = shift;
	} elsif (/^(--clean)$/) {
		$clean++;
	} elsif (/^(--perlver)$/) {
		$perlver = shift;
	} elsif (/^(--usedevel)$/) {
		$usedevel++;
	} else {
		die sprintf ("%s: Unknown option %s.\n", $progname, $_);
	}
}
# sanity checks
if (not defined $clean) {
die sprintf("%s - Error: no variant specified!\n", $progname) if (not defined $variant);
die sprintf("%s - Error: unrecognised variant: '%s'!\n", $progname, $variant)
	if (not defined $names{$variant});
}
die sprintf("%s needs to be run within dpkg-architecture -c !\n", $progname)
	if (not defined $ENV{'DEB_HOST_GNU_TYPE'} or not defined $ENV{'DEB_BUILD_GNU_TYPE'});
die sprintf("%s - Error: nothing to do here, not a cross-build!\n", $progname)
	if ($ENV{'DEB_HOST_GNU_TYPE'} eq $ENV{'DEB_BUILD_GNU_TYPE'});
$arch = $ENV{'DEB_HOST_GNU_TYPE'};
chomp ($arch);
if (not defined $perlver) {
	die sprintf("%s: Cannot find ./debian/config.debian!", $progname)
		if (not -f './debian/config.debian');
	$perlver = `sh ./debian/config.debian --full-version`;
	chomp ($perlver);
}
$rootdir .= "${arch}/${perlver}/";
die sprintf ("%s - %s does not exist!\n", $progname, $rootdir) if (not -d "${rootdir}");
$crossver = `dpkg-query -W -f '\${Version}\n' perl-base`;
chomp ($crossver);
$crossver =~ s/-.*$//;
if (($crossver ne $perlver) and (not defined $usedevel)) {
	die sprintf("Version mismatch with installed perl interpreter: Installed: %s Cross: %s\n",
		$crossver, $perlver);
}
if ($perlver =~ /^5.17/ and defined $usedevel) {
	printf ("Copying in 3 generated header files for %s\n", $perlver) if (not defined $clean);
	push @copying, 'mg_data.h';
	push @copying, 'bitcount.h';
	push @copying, 'uudmap.h';
}
if ($perlver =~ /^5.16/) {
	printf ("Copying in 3 generated header files for %s\n", $perlver) if (not defined $clean);
	push @copying, 'mg_data.h';
	push @copying, 'bitcount.h';
	push @copying, 'uudmap.h';
}
if ($perlver =~ /^5.14/) {
	printf ("Copying in 2 generated header files for %s\n", $perlver) if (not defined $clean);
	push @copying, 'bitcount.h';
	push @copying, 'uudmap.h';
}
if (defined $clean) {
	unlink ('Configure.cross', 'config.sh', 'config.h', 'xconfig.h');
	unlink ('Cross/$(arch)/*.new');
	system ("find lib -name .exists -o -name '*.so' -o -name '*.bs' -o -name '*.ld' | xargs rm -f");
	unlink ("dist/IO/MYMETA.yml", "dist/IO/Makefile", "dist/IO/Makefile.old",
	"lib/IO.pm", "lib/IO/Dir.pm", "lib/IO/File.pm", "lib/IO/Handle.pm",
	"lib/IO/Pipe.pm", "lib/IO/Poll.pm", "lib/IO/Seekable.pm", "lib/IO/Select.pm",
	"lib/IO/Socket.pm", "lib/IO/Socket/INET.pm", "lib/IO/Socket/UNIX.pm");
	unlink (@copying);
	exit (0);
}
if ((not defined $ENV{'DEB_BUILD_OPTIONS'} or $ENV{'DEB_BUILD_OPTIONS'} !~ /nocheck/)
	and (not defined $usedevel)) {
	die sprintf("\n\nCross builds must be called with DEB_BUILD_OPTIONS set to include 'nocheck'!\n\n");
}
# start the work
print "Copy in pre-produced config files for ${perlver} from ${rootdir}, variant $variant\n";

open(USR_H, "${rootdir}config.h.${variant}") or die ($!);
@lines=<USR_H>;
close (USR_H);
open(CFG, ">config.h") or die ($!);
print CFG @lines;
close (CFG);
open(CFG, ">xconfig.h") or die ($!);
print CFG @lines;
close (CFG);

open(USR_SH, "${rootdir}config.sh.${variant}") or die ($!);
@lines=<USR_SH>;
close (USR_SH);
my @out=();
foreach my $line (@lines) {
	$line =~ s:PERL_BUILD_DIR:${srcdir}:g;
	push @out, $line;
}
open(CFG, ">config.sh") or die ($!);
print CFG @out;
close (CFG);
foreach my $file (@copying) {
	open (CPY, "${rootdir}$file") or die ($!);
	my @cpy=<CPY>;
	close (CPY);
	open (GEN, ">$file") or die;
	print GEN @cpy;
	close (GEN);
}

print "Use pre-produced config files to make the Makefiles......\n";

if (defined $usedevel) {
	my $line = "-des -Dusedevel -Dusecrosscompile ";
	$line .= " -Dcc=arm-linux-gnueabi-gcc";
	system ("./Configure $line 2>&1 | tee ../upstream-native.log");
	system ("cp -v host/miniperl miniperl");
	system ("make");
} else {
	open (CON, "${rootdir}../../Configure.cross") or die ($!);
	my @conf=<CON>;
	close (CON);
	open (CRS, ">Configure.cross") or die ($!);
	print CRS @conf;
	close (CRS);
	
	system ("sh ./Configure.cross");
	system ("/usr/bin/perl -Ilib  make_patchnum.pl");
}

sub usageversion {
	warn sprintf ("
%s version %s

Usage:
 %s --variant STR [--rootdir DIR]
 %s --clean
 %s -?|-h|--help|--version

Command:
 --variant STRING - name of the current perl build variant (static, debug, shared)
 --clean          - runs the clean target and exits zero.

Options:
 --rootdir DIR    - debug support for testing with unreleased config files.

", $progname, $ver, $progname, $progname, $progname);
}

sub our_version {
	my $query = `dpkg-query -W -f='\${Version}' perl-cross-debian 2>/dev/null`;
	($query ne "") ? return $query : return "0.0.1";
}
