#!/usr/bin/perl
use File::Basename;
use File::Fetch;
use File::Find;
use File::Copy;
use File::Path qw(make_path remove_tree);
use Cwd qw(abs_path getcwd);


$osname = $^O;
$cwd = getcwd;
print("Current working directory " . $d . "\n");

$coredir = "$cwd/casa-source/casatools/casacore";
$codedir = "$cwd/casa-source/casa5/code";
$corebuilddir = $cwd . "/build/casacorebuild";
$codebuilddir = $cwd . "/build/codebuild";
$targetdir = $cwd . "/build/$osname";
mkdir $cwd . "/build";
mkdir $targetdir;
mkdir $corebuilddir;
mkdir $codebuilddir;

if ( $osname eq "linux" ) {
    $CMAKECORE = "-DUseCcache=1 -DCASA_BUILD=1 -DCMAKE_CXX_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/g++ -DCMAKE_C_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/gcc " .
                 " -DCMAKE_Fortran_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/gfortran -DBoost_NO_BOOST_CMAKE=1 ".
                 "-DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=$targetdir -DCMAKE_BUILD_TYPE=Release $coredir ";
    $CMAKECODE = "-DUseCcache=1  -DUSE_MPI=no -DCMAKE_CXX_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/g++ -DCMAKE_C_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/gcc " .
                 "-DCMAKE_Fortran_COMPILER=/opt/rh/devtoolset-4/root/usr/bin/gfortran -DBoost_NO_BOOST_CMAKE=1 -DEXTRA_C_FLAGS=-DPG_PPU -I/opt/casa/02/include/wcslib " .
                 "-DCMAKE_INSTALL_PREFIX=$targetdir -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF $codedir";
}

if ( $osname eq "darwin" ) {
    $version = `sw_vers -productVersion`;
    @version_elems = split(/\./,$version);
    $version_major = $version_elems[0];
    print("$version_major\n");
    $fortran_version="5";
    if ($version_major > 10) {
        $fortran_version="9";
    }
    $retro_deps="/opt/casa/03";
    if (-e "/opt/casa/02" and -d "/opt/casa/02") {
        $retro_deps="/opt/casa/02";
    }
    print("Building retro components using $retro_deps");
    $CMAKECORE = "-DUseCcache=1 -DCASA_BUILD=1 -DCXX11=1 -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_C_COMPILER=/usr/bin/clang " . 
                 " -DCMAKE_Fortran_COMPILER=$retro_deps/bin/gfortran-mp-$fortran_version -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF " . 
                 "-DPYTHON_LIBRARY=$retro_deps/lib/libpython2.7.dylib -DCMAKE_INSTALL_PREFIX=$targetdir -DBUILD_PYTHON=1 $coredir ";
    $CMAKECODE = "-DUseCcache=1 -DUSE_MPI=no -DCXX11=1 -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_C_COMPILER=/usr/bin/clang " .
                 "-DCMAKE_Fortran_COMPILER=$retro_deps/bin/gfortran-mp-$fortran_version -DLLVMCOMPILER=1 -DREADLINE_ROOT_DIR=$retro_deps " . 
                 "-Darch=darwin -DCMAKE_BUILD_TYPE=Release -DQWT_ROOT_DIR=/opt/casa/03/libexec/qt4 -DINTERACTIVE_ITERATION=1 -Dpgplot_ext=_nox -DCMAKE_INSTALL_PREFIX=$targetdir $codedir";
}


print("\nCasacore flags:\n" . $CMAKECORE . "\n\n");
print("Code flags:\n" . $CMAKECODE . "\n");


### build casacore...
$corebuilddir = build("<core>", $corebuilddir,$CMAKECORE,"install");
### install casacore version.h file...
$install_version = sub {
    if ( -f $_ && $_ eq "version.h" ) {
        copy( $_, $coresrcdir );
    }
};
find( $install_version, $corebuilddir );
### build casa code
$codebuilddir = build( "<code>", $codebuilddir, $CMAKECODE );

if ( $osname eq "linux" ) {
    open( CMAKE, "cp -r $targetdir/bin/CrashReportPoster $cwd/casatelemetry/__bin__/ 2>&1 |" ) or die $!;
    print("\t---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n");
    print("\t$label cmake $flags\n");
    while ( <CMAKE> ) {
        print("\t$label $_");
    }
    close(CMAKE) or warn $! ? "error closing cmake pipe: $!" : "exit status $? from cmake";
}
if ( $osname eq "darwin" ) {
    open( CMAKE, "cp -r $targetdir/apps/CrashReportPoster.app $cwd/casatelemetry/__bin__/casacrashreportposter/ 2>&1 |" ) or die $!;
    print("\t---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n");
    print("\t$label cmake $flags\n");
    while ( <CMAKE> ) {
        print("\t$label $_");
    }
    close(CMAKE) or warn $! ? "error closing cmake pipe: $!" : "exit status $? from cmake";
    
}

sub build {
    my $label = shift(@_);
    my $path = shift(@_);
    my $flags = shift(@_);
    my $tgt =  scalar(@_) > 0 ? shift(@_) : "";
    my $d = getcwd;
    print("\t$label cd $path\n");
    chdir($path) or die "could not change to $path: $!";
    print ("PATH: $path\n");
    print ("cwd: $d\n");
    print ("flags: $flags\n");
    open( CMAKE, "cmake $flags 2>&1 |" ) or die $!;
    print("\t---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n");
    print("\t$label cmake $flags\n");
    while ( <CMAKE> ) {
        print("\t$label $_");
    }
    close(CMAKE) or warn $! ? "error closing cmake pipe: $!" : "exit status $? from cmake";
    print("\t---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n");
    $ncores="";
    if ($osname == "linux") { $ncores = "-j " . `nproc`; }
    else { $ncores = "-j " . `sysctl -n hw.ncpu`/2; }
    open( MAKE, $tgt ? "make $tgt 2>&1 |" : "make 2>&1 |" );
    while ( <MAKE> ) {
        print("\t$label $_");
    }
    close(MAKE) or warn $! ? "error closing make pipe: $!" : "exit status $? from make";
    print("exit status $? from make");
    if ($? != 0) {
        print("Retro component compilation failed.");
        exit $?;
    }
    chdir($d);
    return $path;
}