#!/usr/bin/perl -w
use strict;


sub usage 
{
	print "debbuild.pl --buildroot sameBuildPathAsRPM -bb specFileForTheRPM --target arch\n";
}

if(@ARGV < 6) { die usage() }
my ($buildroot, $specfile, $target);

while(@ARGV)
{
	my $arg = shift || die usage();
	if($arg eq '--buildroot')
	{
		$buildroot = shift || die "Pass the buildroot!\n";
	}
	elsif($arg eq '-bb')
	{
		$specfile = shift || die "Pass the specfile!\n";
	}
	elsif($arg eq '--target')
	{
		$target = shift || die "Pass the arch!\n";
	}
}

my %nameMapping = ( 'preun' => 'prerm', 'post' => 'postinst', 'postun' => 'postrm', 'control' => 'control',
	'prep' => 'preinst');

my $state = 'control';
my %internalStreams = ('postun' => '', 'preun' => "#!/bin/sh -e\n", 'postun' => "#!/bin/sh -e\n",
	'control' => '', 'prep' => "#!/bin/sh -e\n", 'build' => '', 'install' => '', 'files' => '',
	'clean' => '', 'post' => "#!/bin/sh -e\n", 'description' => '', 'debian-binary' => "2.0\n");
	
	$internalStreams{$state} .= "Architecture: $target\n";
	
my %dirHash;
	
#MAIN
parseTheSpecFile();
print "finished parsing.\n";
buildDeb();
print "finished building.\n";

#ENDMAIN

sub dieDK{
	my $str = shift;
	die print "I don't know $str\n";
}

sub parseTheSpecFile
{
	open my $sfh, '<', $specfile or die "Could not open spec file:\n$!\n"; 
	while(<$sfh>)
	{
		#change state? 
		if(/^%(\w+)$/)
		{
			$state = $1;
			dieDK($state) unless exists $internalStreams{$state};
		}
		elsif(/^(\w+): (.+)$/)
		{
			dieDK("param input other the control.") unless $state eq 'control';
			my $name = $1;
			my $str = $2;
			if($name eq 'Name')
			{
				$internalStreams{$state} .= "Package: $2\n";
			} elsif ($name eq 'Version')
			{
				$internalStreams{$state} .= "Version: $2\n";
			} elsif ($name eq 'Vendor')
			{
				$internalStreams{$state} .= "Maintainer: $2 ".'<support@Ecrion.com>'."\n";
			}
		}
		else
		{
			if($state eq 'post' || $state eq 'preun' || 
				     $state eq 'postun' || $state eq 'description')
			{
				$internalStreams{$state} .= $_;
			}
			elsif( $state eq 'files')
			{
				chomp;
				my @dirStack;
				while(m!([^/"]+)/!g)
				{
					push @dirStack, $1;
					my $dir = '/';
					map{ 
						$dir .= "$_/";
					} @dirStack;
					if(!exists $dirHash{$dir}) {
						$internalStreams{'prep'} .= "[ -d \"$dir\" ] || mkdir \"$dir\"\n";
						$dirHash{$dir} = 1;		
					} 
				}
				$_ =~ s/"\//".\//;
				$internalStreams{$state} .= " $_";
			}
			else
			{
				dieDK($state) unless $_ eq "\n";
			}
		}
		
	}
	if(length $internalStreams{'description'} > 0)
	{
		$internalStreams{'control'} .= "Description: ".$internalStreams{'description'}; 
	} else {
		$internalStreams{'control'} .= "Description: No Description.\n";
	}
}

sub buildDeb
{
	my $workPlace = '/root/Workplace';
	$workPlace = '/root' unless -d $workPlace;
		
	`rm -rf $workPlace/control` if -d "$workPlace/control";
	
	`rm -rf $workPlace/data` if -d "$workPlace/data";
	
	#building control.tar.gz
	#write the scripts to files, chmod them to be executable
	
	`mkdir $workPlace/control`;
	
	my $controldir = "$workPlace/control";
	
	map {
		open my $tempf, '>', "$controldir/$nameMapping{$_}" or die $!;
		print $tempf $internalStreams{$_};
		close $tempf;
		`chmod 755 "$controldir/$nameMapping{$_}"` unless $_ eq 'control';		
	} keys %nameMapping;
	
	chdir $controldir;
	
	`tar czf $workPlace/control.tar.gz *`;
	
	chdir $workPlace;
	
	`rm -rf $workPlace/control`;
	
	#build data.tar.gz
	#tar.gz buildroot
	
	chdir $buildroot;
	
	`tar czf $workPlace/data.tar.gz $internalStreams{'files'}`;
	
	chdir $workPlace;
	
	#build the deb
	open my $fh, '>', "$workPlace/debian-binary" or die $!;
	print $fh $internalStreams{'debian-binary'};
	close $fh;
	
	my $buildOutputDir = 'DEBS/';
	`mkdir $workPlace/$buildOutputDir` unless -d "$workPlace/$buildOutputDir";
	$buildOutputDir .= "$target/";
	`mkdir $workPlace/$buildOutputDir` unless -d "$workPlace/$buildOutputDir";
	my $archiveName;
	
	if($buildroot =~ m!/([^/]+)/$!)
	{
		$archiveName = "$1.deb";
	} else {
		$archiveName = "build.deb";
	}
	
	`rm $workPlace/$buildOutputDir/$archiveName` if -e "$workPlace/$buildOutputDir/$archiveName";
	`ar cq $workPlace/$buildOutputDir/$archiveName $workPlace/debian-binary $workPlace/control.tar.gz $workPlace/data.tar.gz`;
	 
	`rm $workPlace/data.tar.gz`;
	`rm $workPlace/control.tar.gz`;
	`rm $workPlace/debian-binary`;
}