
use strict ;
use warnings ;

use Module::Build;

my %all_modules ;
my @split_modules ;

my @pm_files = qw(
PBS/Attributes.pm
PBS/Build.pm
PBS/Build/NodeBuilder.pm
PBS/Build/Threaded.pm
PBS/Build/Forked.pm
PBS/Build/ForkedNodeBuilder.pm
PBS/Build/LightWeightServer.pm
PBS/Check.pm
PBS/Cyclic.pm
PBS/Config.pm
PBS/Constants.pm
PBS/DefaultBuild.pm
PBS/Debug.pm
PBS/Depend.pm
PBS/Digest.pm
PBS/Distributor.pm
PBS/Documentation.pm
PBS/FrontEnd.pm
PBS/Graph.pm
PBS/Graph/Html.pm
PBS/Graph/Snapshots.pm
PBS/GraphViz.pm
PBS/Output.pm
PBS/PBS.pm
PBS/Prf.pm
PBS/PBSConfig.pm
PBS/PBSConfigSwitches.pm
PBS/Plugin.pm
PBS/ProgressBar.pm
PBS/Rules.pm
PBS/Rules.pm
PBS/Rules/Dependers.pm
PBS/Rules/Dependers/Subpbs.pm
PBS/Rules/Creator.pm
PBS/Rules/Builders.pm
PBS/Rules/Metarules.pm
PBS/Triggers.pm
PBS/PostBuild.pm
PBS/Shell.pm
PBS/Shell/SSH.pm
PBS/Shell/Telnet.pm
PBS/Wizard.pm
PBS/Information.pm
PBS/Log.pm
PBS/Warp.pm
PBS/Warp/Warp0.pm
PBS/Warp/Warp1_5.pm
PBS/Warp/Warp1_7.pm
PBS/Warp/Warp1_8.pm
PBS/SubpbsResult.pm
PBS/Watch/InotifyWatcher.pm
PBS/Watch/Win32Watcher.pm
PBS/Watch/Client.pm

PBS/Version.pm
);

for(@pm_files)
	{
	$all_modules{$_} = "lib/$_" ;
	push @split_modules, $_ ;
	}

my @extra_modules =
qw(
Plugins/CheckNodeName.pm
Plugins/CreateDump.pm
Plugins/CreateLog.pm
Plugins/EvaluateShellCommand.pm
Plugins/ExpandObjects.pm
Plugins/FileWatchClient.pm
Plugins/GraphGeneration.pm
Plugins/PackageVisualisation.pm
Plugins/PostPbs.pm
Plugins/SimplifyRule.pm
Plugins/TreeVisualisation.pm
Plugins/Visualisation.pm
) ;

for(@extra_modules)
        {
        $all_modules{$_} = "lib/PBS/$_" ;
        }

my @PBSLib =
qw(

PBSLib/Builders/SingleRunBuilder.pm
PBSLib/Builders/Objects.pm

PBSLib/Configs/Compilers/cl.pm
PBSLib/Configs/Compilers/compiler.pm
PBSLib/Configs/Compilers/gcc.pm
PBSLib/Configs/Compilers/old_gcc.pm
PBSLib/Configs/ConfigureProject.pm
PBSLib/Configs/ConfigureProjectVariablesAndRules.pm
PBSLib/Configs/ShellCommands.pm

PBSLib/Dependers/Locator.pm
PBSLib/Dependers/Matchers.pm

PBSLib/Language/Simplified.pm

PBSLib/MetaRules/FirstAndOnlyOneOnDisk.pm

PBSLib/Rules/C.pm
PBSLib/Rules/C_DependAndBuild.pm
PBSLib/Rules/C_depender.pm

PBSLib/Rules/Compilers/cl.pm
PBSLib/Rules/Compilers/compiler.pm
PBSLib/Rules/Compilers/gcc.pm

PBSLib/Rules/NodeSubs/Config.pm

PBSLib/Rules/VisualStudioDSP.pm
PBSLib/Rules/VisualStudioProject.pm
PBSLib/Rules/cl_pch.pm

PBSLib/UserBuild/BuildSequenceMiner.pm
PBSLib/UserBuild/Multiple_O_Compile.pm

PBSLib/Utils/VisualStudioProjectFile.pm

PBSLib/Wizards/Breakpoint.pl
PBSLib/Wizards/BuilderSub.pl
PBSLib/Wizards/Creator.pl
PBSLib/Wizards/Distributor.pl
PBSLib/Wizards/NodeSub.pl
PBSLib/Wizards/Plugin.pl
PBSLib/Wizards/PostPbs.pl
PBSLib/Wizards/Prf.pl
PBSLib/Wizards/SimpleDependerSub.pl
PBSLib/Wizards/StandardPbsfile.pl
PBSLib/Wizards/Subpbs.pl
PBSLib/Wizards/menu.pl
PBSLib/Wizards/template.pl
) ;

for(@PBSLib)
	{
	$all_modules{$_} = "lib/PBS/$_" ;
	}


sub GetVersionandRevisionFrom
{
my ($file) = @_ ;

my $version_from = File::Spec->catfile( split '/', $file );
my $version      = Module::Build->version_from_file($version_from);

if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my @svk_log = `svk log -r HEAD -q` ;
	if(@svk_log)
		{
		my ($revision) = $svk_log[1] =~ m/^r([0-9]+):/ ;
		print "using SVK revision $revision.\n" ;
		return("${version}.${revision}") ;
		}
	else
		{
		print "Couldn't get SVK revision, using version from '$file'!\n" ;
		return($version) ;
		}
	}
else
	{
	return($version) ;
	}
}

my $code = <<'EOC'
#~ use Data::TreeDumper ;
#~ print DumpTree \@_, 'args:' ;

sub GetVersionandRevisionFrom
{
my ($file) = @_ ;

my $version_from = File::Spec->catfile( split '/', $file );
my $version      = Module::Build->version_from_file($version_from);

if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my @svk_log = `svk log -r HEAD -q` ;
	if(@svk_log)
		{
		my ($revision) = $svk_log[1] =~ m/^r([0-9]+):/ ;
		print "using SVK revision $revision.\n" ;
		return("${version}.${revision}") ;
		}
	else
		{
		print "Couldn't get SVK revision, using version from '$file'!\n" ;
		return($version) ;
		}
	}
else
	{
	return($version) ;
	}
}

#~ sub ACTION_
#~ {
#~ my $self = shift;
#~ print "\n";
#~ }

sub ACTION_build 
{
my $self = shift;

if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my ($pbs_version) = GetVersionandRevisionFrom('PBS/FrontEnd.pm') ;
	
	print "Generating version module ($pbs_version)\n" ;
	
	open VERSION, '>', 'PBS/Version.pm' or die "can't generate Version module: $!\n" ;
	
	print VERSION <<EOV ;
	
	# version module automatically generated by the build system
	
	package PBS::Version ;
	
	sub GetVersion {return '$pbs_version'} ;
	
	1 ;
	
	# end of generated version module
EOV
	
	close VERSION ;
	}
	
$self->SUPER::ACTION_build(@_);
}

sub ACTION_latest
{
ACTION_dist(@_) ;
if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my ($pbs_version) = GetVersionandRevisionFrom('PBS/FrontEnd.pm') ;
	
	my $source = "PerlBuildSystem-$pbs_version.tar.gz" ;
	my $destination = "PerlBuildSystem-latest.tar.gz" ;
	
	use Net::SCP qw(scp iscp);
	iscp($source, "nadim\@firewall:/var/www/localhost/htdocs/files_for_download/$destination");
	}
}

sub ACTION_dist
{
my $self = shift;

if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my $have_svk = $self->do_system('svk --version');
	
	if($have_svk)
		{
		if($self->do_system('svk log -x -v > SVK_Changes'))
			{
			use File::Copy;
			move('SVK_Changes', 'Changes') ;
			}
		else
			{
			print "Couldn't get SVK log, 'Changes' will not be generated from SVK log!\n" ;
			}
		}
	else
		{
		print "SVK not found, 'Changes' will not be generated from SVK log!\n" ;
		}
	}
	
$self->SUPER::ACTION_dist();

if($ENV{PBS_USE_SVK_VERSION_FOR_DIST})
	{
	my ($pbs_version) = GetVersionandRevisionFrom('PBS/FrontEnd.pm') ;
	
	my $source = "PerlBuildSystem-$pbs_version.tar.gz" ;
	my $destination = "PerlBuildSystem-bleed.tar.gz" ;
	
	use Net::SCP qw(scp iscp);
	iscp($source, "nadim\@firewall:/var/www/localhost/htdocs/files_for_download/$destination");
	}
};

sub ACTION_inject
{
#~ my $self = shift;

# check cpan if mini inject is installed
# build
# from $self find how to update 02packages.details.txt.gz

die "'inject' not implemented yet!\n";
}

#~ sub ACTION_
#~ {
#~ my $self = shift;
#~ print "\n";
#~ }

sub ACTION_update_cpan_mini
{
# build test and make a dist
die "'update_mini_cpan' not implemented yet!\n";
}

EOC
;

my $class = Module::Build->subclass(class => 'PBS::Builder', code => $code) ;

my $build = $class->new
	(
	module_name => 'PerlBuildSystem',
	
	dist_version => GetVersionandRevisionFrom('PBS/FrontEnd.pm'),
	
	license => 'perl',
	
	requires => 
		{
		'Module::Build'       => '0.2611',
		'Module::Util'       => '0.2611',
		'Data::TreeDumper'    => '0.24',
		'Getopt::Long'        => '2.32',
		'Cwd'                 => '2.06',
		'Data::Dumper'        => '2.12',
		'Data::Compare'       => '0',
		'File::Basename'      => '2.71',
		'Tie::Hash::Indexed'  => '0.03',
		'Devel::Depend::Cpp'  => '0.05',
		'Devel::Depend::Cl'   => '0.01',
		'Devel::Cycle'        => '0',
		'File::MkTemp'        => '0',
		'Pod::Simple::Search' => '0',
		'Data::Compare'       => '0',
		'Test::Class'         => '0',
		'Test::Cmd'           => '0',
		'File::Spec'          => '0',
		'File::Slurp'         => '0',
		'IO::String'          => '0',
		'File::Copy::Recursive' => '0',
		'Class::MethodMaker' => '0',
	        'Term::ReadKey' => '0',

		'Devel::Depend::Cpp'  => '0.08',
		'Devel::Depend::Cl'   => '0.04',
		
		#'GraphViz'            => '0',
		#'Math::Bezier'        => '0',
		#'Math::Pari'          => '0',
		#'Net::Telnet'         => '0',
		#'Net::SSH::Perl'      => '0',
		
		#'Term::ANSIColor' => '0',
		#'Text::Balanced' => '0',
		},
		
	pm_files     => \%all_modules,
	autosplit    => \@split_modules,
	
	script_files => 'script/pbs.pl',
	dist_author  => 'Khemir Nadim ibn Hamouda. <nadim@khemir.net>',
	dist_abstract => 'Build utility/modules in the same spirit as gmake',
	);
	
$build->create_build_script;
  
