#  Copyright (c) 2018
#  Charles Jordan (Hokkaido University, Sapporo, Japan),
#  Michael Joswig, Lars Kastner (Technische Universitaet Berlin, Germany)
# 
#  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 3, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
# 
#  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.
#-------------------------------------------------------------------------------

use strict;
use Cwd;
use Config;
use File::Path;

use vars '$root', '%ConfigFlags';
my ($targets_file, $config_file);
($targets_file, $root, $config_file)=@ARGV;

unless (@ARGV==3 && -f $config_file && -d $root) {
   die "usage: $0 BUILD_ROOT/targets.ninja PROJECT_TOP BUILD_ROOT/config.ninja\n";
}

do "$root/support/install_utils.pl";
die $@ if $@;

# for file in src{,-reg,-mp}/*.cc; do perl bla.pl `basename $file .cc`; done > support/deps.txt
my %deps;
open my $depfile, "<","$root/support/deps.txt" or die "no deps!";
while (<$depfile>) {
   next if /^\s*$/;
   my ($target,$dep) = split(": ",$_);
   chomp $dep;
   $deps{$target} = [split(" ",$dep)];
}

my $buildroot=dirname($config_file);
%ConfigFlags=load_config_file($config_file, $root);

my $core_mode=!exists $ConfigFlags{extroot};
my $srcroot= $core_mode ? $root : $ConfigFlags{extroot};
my $srcrootname= $core_mode ? '${root}' : '${extroot}';
my $DeveloperMode=-d "$srcroot/.git";


open(my $out_file, ">$targets_file") or die "Cannot write to $targets_file.";

print $out_file
   
# Ompi is handled by appending the string "_ompi" to the rule of the
# rules.ninja file. For the regular TOPCOM files we do not want to build with
# mpic{c,xx}.
my $mpi = "";
my @all = ();
foreach my $file (glob "$srcroot/lib-src*/*.cc"){
   process_cc_file($file, '${builddir}', $out_file, $mpi);
}

foreach my $file (glob "$srcroot/src{,-reg}/*.cc"){
   process_cc_file($file, '${builddir}', $out_file);
   push @all, process_binary_file($file, '${builddir}', $out_file, $mpi);
}

# From here on we build mptopcom, so activate mpi option.
$mpi = "_mpi";

foreach my $file (glob "$srcroot/src-mp/*.{c,cc}"){
   process_cc_file($file, '${builddir}', $out_file, $mpi);
}

push @all, process_binary_file("$srcroot/src-mp/mptopcom.cc", '${builddir}', $out_file, $mpi);

print $out_file <<"---";
build install: install_core || all
build all: phony @all
default all
---

close($out_file);

exit 0;

###############################################################################
###############################################################################

sub process_binary_file {
   my($src_file, $out_dir, $out_file, $mpi) = @_;
   my $subdir = $src_file;
   my ($src_name, $obj_name)=basename($src_file, "(?:cc|cpp|C)");
   $subdir =~ s/\/$src_name//;
   $subdir =~ s/^\Q$srcroot\E\///;
   my $libfiles = join(" ",map {"\${builddir}/$_"} @{$deps{$subdir."/".$obj_name}});
   my $in=$out_dir."/".$subdir."/".$obj_name.".o ".$libfiles." ";
   
   $obj_name="$out_dir/bin/$obj_name";
   print $out_file
      "build $obj_name : binary$mpi $in\n";
   print $out_file "\n";
   return $obj_name;
}

sub process_cc_file {
   my($src_file, $out_dir, $out_file, $mpi) = @_;
   my $subdir = $src_file;
   my ($src_name, $obj_name)=basename($src_file, "(?:c|cc|cpp|C)");
   $subdir =~ s/\/$src_name//;
   $src_file =~ s/^\Q$srcroot\E/$srcrootname/;
   $subdir =~ s/^\Q$srcroot\E\///;
   $obj_name="$out_dir/$subdir/$obj_name.o";
   my $xx = "";
   unless ($src_file =~ /\.c$/) {
      $xx = "xx";
   }
   
   print $out_file
      "build $obj_name : c${xx}compile$mpi $src_file\n";
   print $out_file "\n";
}


# Local Variables:
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
