#!/usr/bin/perl
# Download third-party packages independently of FF configuration (request from FH)
# ======================================================================
# Written by Antoine Le Hyaric
# http://www.ljll.math.upmc.fr/lehyaric
# Laboratoire Jacques-Louis Lions
# Université Pierre et Marie Curie-Paris6, UMR 7598, Paris, F-75005 France
# ======================================================================
# This file is part of Freefem++
#
# Freefem++ is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Freefem++ 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with Freefem++; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# ======================================================================
# headeralh brief="Download third-party packages independently of FF configuration (request from FH)" default=0 freefem perl start=21/10/2013 upmc written

use strict;
use Getopt::Std;
use Digest::MD5 qw(md5_hex); # [[http://perldoc.perl.org/Digest/MD5.html]]

# This download script needs to be able to work on platforms that do not have threads (eg Mingw).

my $can_use_threads=eval 'use threads;use threads::shared;1';

my %opts;
getopts('afho:',\%opts);

if($opts{h}){
  print <<EOF;
getall [options]: Download third-party packages independently of the FreeFem++ configuration procedure

Available options:

-a = accept all licences without further user interaction
-f = force downloads even if packages are already present locally
-h = this help
-o name,name,... = only download packages with the given names

EOF
  exit 0;
}

# Accumulate errors and print them all at the end of the script

my $errors='';
if($can_use_threads){share(\$errors)}

# list required packages
my $only=0;
my %packs;
if(defined $opts{o}){
  $only=1;
  foreach(split(/,/,$opts{o})){$packs{$_}=1}
}

# can be run from the parent directory

if(-x "download/getall"){chdir "download"}

# can be run from any of the child directories

if(-x "../getall"){chdir ".."}

system "mkdir -p pkg";
my @downloads;

download('ARPACK','http://www.caam.rice.edu/software/ARPACK/SRC/arpack96.tar.gz',
	 'http://www.caam.rice.edu/software/ARPACK','arpack96.tar.gz','fffaa970198b285676f4156cebc8626e');
download('ARPACK','http://www.caam.rice.edu/software/ARPACK/SRC/patch.tar.gz',
	 'http://www.caam.rice.edu/software/ARPACK','patch.tar.gz','14830d758f195f272b8594a493501fa2');

download('BLAS','http://www.netlib.org/blas/blas.tgz','http://www.netlib.org/blas','blas.tgz',
	 'ca21ed426f347c6ec6b136a181e587e5');
download('BLAS','http://www.netlib.org/blas/blast-forum/cblas.tgz','http://www.netlib.org/blas','cblas.tgz',
	 '1e8830f622d2112239a4a8a83b84209a');

download('OpenBLAS','http://github.com/xianyi/OpenBLAS/tarball/v0.2.12','http://www.openblas.net/','OpenBLAS.tar.gz',
	 'dfc868e0c134855639f036d2723bf4be',
	 'BAD_CERT');

download('FFTW','http://www.fftw.org/fftw-3.3.2.tar.gz','http://www.fftw.org','fftw-3.3.2.tar.gz',
	 '6977ee770ed68c85698c7168ffa6e178');

download('freeYams','http://www.ann.jussieu.fr/~frey/ftp/archives/freeyams.2012.02.05.tgz',
	 'http://www.ann.jussieu.fr/~frey/software.html','freeyams.2012.02.05.tgz','b7c82a256a3e59beeb2b578de93a4e0b');

download('Gmm++','http://download.gna.org/getfem/stable/gmm-4.2.tar.gz',
	 'http://download.gna.org/getfem/html/homepage/download.html','gmm-4.2.tar.gz','35fe900f7459c49f4b4337dc691c8cdf');

download('Hips','http://hips.gforge.inria.fr/release/hips-1.2b-rc4.tar.gz',
	 'http://hips.gforge.inria.fr/','hips-1.2b-rc4.tar.gz','78720bf9bbbce5e174bdbdbaa1e5d7b4');

download('Ipopt','http://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.4.tgz',
	 'https://projects.coin-or.org/Ipopt','Ipopt-3.12.4.tgz','12a8ecaff8dd90025ddea6c65b49cb03');

#download('METIS','http://www.netlib.org/linalg/metis-4.0.tar.gz','http://www.netlib.org/linalg/','metis-4.0.tar.gz',
#	 '0aa546419ff7ef50bd86ce1ec7f727c7');
download('METIS','http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz','http://www.netlib.org/linalg/','metis-5.1.0.tar.gz',
	 '5465e67079419a69e0116de24fce58fe');


#download('ParMETIS','http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/OLD/ParMetis-3.1.1.tar.gz',
#	 'http://glaros.dtc.umn.edu/gkhome/views/metis','ParMetis-3.1.1.tar.gz','57318dbaddff2c3d1ef820cff0bf87b0');
download('ParMETIS','http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/parmetis-4.0.3.tar.gz',
	 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/','ParMetis-4.0.3.tar.gz','f69c479586bf6bb7aff6a9bc0c739628');
# http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/parmetis-4.0.3.tar.gz
download('MMG3D','http://www.math.u-bordeaux1.fr/~dobrzyns/logiciels/download/mmg3d4.0.tgz',
	 'http://www.math.u-bordeaux1.fr/~dobrzyns/logiciels/mmg3d.php','mmg3d4.0.tgz','bfc2b0373bc208e0512415d1aa2e76a1');

download('mshmet','http://www.ann.jussieu.fr/~frey/ftp/archives/mshmet.2012.04.25.tgz',
	 'http://www.ann.jussieu.fr/~frey/software.html','mshmet.2012.04.25.tgz','427f397e0602efc56aa897d38a8e9bfa');

#download('MUMPS','http://graal.ens-lyon.fr/MUMPS/MUMPS_4.10.0.tar.gz',
#	 'http://graal.ens-lyon.fr/MUMPS/','MUMPS_4.10.0.tar.gz','959e9981b606cd574f713b8422ef0d9f');
#download('MUMPS','http://graal.ens-lyon.fr/MUMPS/MUMPS_5.0.0.tar.gz',
#	 'http://graal.ens-lyon.fr/MUMPS/','MUMPS_5.0.0.tar.gz','3c6aeab847e9d775ca160194a9db2b75');
download('MUMPS','http://graal.ens-lyon.fr/MUMPS/MUMPS_5.0.1.tar.gz',
	 'http://graal.ens-lyon.fr/MUMPS/','MUMPS_5.0.1.tar.gz','b477573fdcc87babe861f62316833db0');

download('NLopt','http://ab-initio.mit.edu/nlopt/nlopt-2.2.4.tar.gz',
	 'http://ab-initio.mit.edu/wiki/index.php/NLopt','nlopt-2.2.4.tar.gz','9c60c6380a10c6d2a06895f0e8756d4f');

download('pARMS','http://www-users.cs.umn.edu/~saad/software/pARMS/pARMS_2.2.php',
	 'http://www-users.cs.umn.edu/~saad/software/pARMS','pARMS_2.2.tar.gz','be0b4a539d78b9b2b7faf32ff83de822');

# ALH - 6/1/14 - web certificate for gforge.inria.fr is rejected

download('PaStiX','https://gforge.inria.fr/frs/download.php/21873/pastix_release_2200.tar.bz2',
	 'https://gforge.inria.fr/projects/pastix/','pastix_release_2200.tar.bz2','c82b1808084f183dc8dfd07b1deef694',
	 'BAD_CERT');

download('ScaLAPACK','http://www.netlib.org/scalapack/scalapack-2.0.2.tgz',
	 'http://www.netlib.org/scalapack/','scalapack-2.0.2.tgz','2f75e600a2ba155ed9ce974a1c4b536f');

# ALH - 6/1/14 - web certificate for gforge.inria.fr is rejected
#https://gforge.inria.fr/frs/download.php/file/34099/scotch_6.0.3.tar.gz
#download('Scotch','https://gforge.inria.fr/frs/download.php/file/34099/scotch_6.0.3.tar.gz',
#	 'https://gforge.inria.fr/projects/scotch/','scotch_6.0.3.tar.gz','10b0cc0f184de2de99859eafaca83cfc',
#	 'BAD_CERT');
download('Scotch','https://gforge.inria.fr/frs/download.php/file/34618/scotch_6.0.4.tar.gz',
	 'https://gforge.inria.fr/projects/scotch/','scotch_6.0.4.tar.gz','d58b825eb95e1db77efe8c6ff42d329f',
	 'BAD_CERT');

# download('SuiteSparse','http://www.cise.ufl.edu/research/sparse/SuiteSparse/SuiteSparse-4.3.1.tar.gz',
# 	 'http://www.cise.ufl.edu/research/sparse/SuiteSparse/','SuiteSparse-4.3.1.tar.gz',
# 	 'f8f26a3b1c7f82444c0db0b375215287');

download('SuiteSparse','http://faculty.cse.tamu.edu/davis/SuiteSparse/SuiteSparse-4.4.4.tar.gz',
	 'http://faculty.cse.tamu.edu/davis/SuiteSparse/','SuiteSparse-4.4.4.tar.gz',
	 'e0af74476935c9ff6d971df8bb6b82fc') ;

download('SuperLU','http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_4.3.tar.gz',
	 'http://crd-legacy.lbl.gov/~xiaoye/SuperLU/','superlu_4.3.tar.gz','b72c6309f25e9660133007b82621ba7c');
download('SuperLU_DIST','http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_dist_3.0.tar.gz',
	 'http://crd-legacy.lbl.gov/~xiaoye/SuperLU/','superlu_dist_3.0.tar.gz','1d77f10a265f5751d4e4b59317d778f8');
# http://www.tetgen.org/1.5/src/tetgen1.5.1-beta1.tar.gz
#download('TetGen','http://wias-berlin.de/software/tetgen/files/tetgen1.4.3.tar.gz',
#	 'http://wias-berlin.de/software/tetgen/','tetgen1.4.3.tar.gz','d6a4bcdde2ac804f7ec66c29dcb63c18');
download('TetGen','http://www.tetgen.org/1.5/src/tetgen1.5.1-beta1.tar.gz',
	 'http://www.tetgen.org/1.5/src/','tetgen1.5.1-beta1.tar.gz','3d55c197bcbfc611b7ced6f343643756');

#download('PETSc','http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-lite-3.5.2.tar.gz',
#	 'http://ftp.mcs.anl.gov/pub/petsc/release-snapshots','petsc-lite-3.5.2.tar.gz','d707336a98d7cb31d843804d020edc94');
download('hpddm','https://github.com/hpddm/hpddm/archive/6bb4d040fb8919b80bcbd1126302efc8ee9a33cf.zip',
	 'https://github.com/hpddm','hpddm.zip','2d35bad7739e230771493d66c1dc8447','BAD_CERT');

# run all downloads concurrently

if($can_use_threads){
  my @threads;
  foreach(@downloads){push @threads,threads->create(\&downloadone,$_)}
  foreach(@threads){$_->join()}
}
else{
  foreach(@downloads){downloadone($_)}
}

if($errors ne ''){
  print "\n$errors";
  exit 1;
}

sub download{
  my($title,$url,$lic,$pkg,$md5,$opts)=@_;

  # skip packages that have not been requested explicitely
  return if($only && !defined $packs{$title});

  # skip packages that are already present
  if(-f "pkg/$pkg" && !$opts{f}){
    my $md5check=md5_hex(`cat pkg/$pkg`);
  if( ( $md5 eq "none") || ($md5check eq $md5))
   {
    print "$title $pkg done\n";
    return;
   }

  else {
   print "$title $pkg  md5 change => reget \n";
    }
  }

  # we do not store the answers to these questions. To repeat the same downloads without manual input, options "-a" and
  # "-o names" are provided.

  if(!$opts{a}){
    print "$title: please check the licence at $lic. Do you want to download $url? (yN)\n";
    my $ans=uc <STDIN>;
    chomp $ans;
    return if $ans ne 'Y';
  }

  # uses [[file:../build/download]]
  push @downloads,"$url,pkg/$pkg,$md5,$opts";
}

sub downloadone{
  my($url,$pkg,$md5,$opts)=split(/,/,$_[0]);
  my $cmd="../build/download $url $pkg $opts";
  print "$cmd\n";
  system $cmd;
  if($?){
   my $cmd="../build/download http://www.freefem.org/ff++/$pkg $pkg $opts";
   print "try other site: $cmd\n";
   system $cmd;
   if($?){
     $errors.="ERROR: $cmd FAILED\n"}
  }
  # check if resulting package contents are valid
  my $md5check=md5_hex(`cat $pkg`);
  if( ( $md5 ne "none") && ($md5check ne $md5)){$errors.="ERROR: INVALID MD5 for $pkg\n"}
}

# Local Variables:
# mode:cperl
# ispell-local-dictionary:"british"
# coding:utf-8
# End:
