#  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 warnings;
use application 'polytope';

# This file uses polymake to check whether we still get the same output in the
# testfiles. Call it from root with:
#
# polymake --script support/update_make_tree_tests.pl
#
# This is necessary since TOPCOM does not always output its triangulations
# sorted, e.g.:
#
# -21: [0->12,6:{{0,4,5,6,7,8},{0,5,6,7,8,10},{0,2,5,6,7,10},{0,2,3,5,7,10},{0,1,2,3,5,10},{1,5,8,9,10,11},{1,3,5,8,10,11},{3,5,7,8,10,11},{0,1,3,5,8,10},{0,3,5,7,8,10}}] gkz: [7,4,3,6,1,10,3,6,7,1,9,3] can(gkz): [10,6,3,1,4,6,3,7,1,3,9,7]
# +21: [0->12,6:{{0,4,5,6,7,8},{0,5,6,7,8,10},{0,2,5,6,7,10},{0,2,3,5,7,10},{1,5,8,9,10,11},{0,1,2,3,5,10},{1,3,5,8,10,11},{3,5,7,8,10,11},{0,1,3,5,8,10},{0,3,5,7,8,10}}] gkz: [7,4,3,6,1,10,3,6,7,1,9,3] can(gkz): [10,6,3,1,4,6,3,7,1,3,9,7]
#
# These are the same triangulation, but the simplices are sorted differently.

my $mptopcom1 = "./build/Opt/bin/mptopcom1";
if(!-e $mptopcom1){
   die("mptopcom1 executable not found.");
}

my @files = split("\n", `find testfiles/`);
@files = grep($_ =~ m/.*tree/, @files);
my @make_tree = grep($_ =~ m/.*make-tree/, @files);
my @make_marked_tree = grep($_ =~ m/.*make-marked-tree/, @files);

print "MT:\n",join("\n",@make_tree),"\n";
print "MMT:\n",join("\n",@make_marked_tree),"\n";

foreach my $file(@make_tree){
   update_file($file, "make-tree");
}
foreach my $file(@make_marked_tree){
   update_file($file, "make-marked-tree");
}

sub update_file {
   my($file, $opt) = @_;
   print "Updating $file ... ";
   my($example) = $file =~ m/testfiles\/(.*)\.$opt/x;
   my $output = `./build/Opt/bin/mptopcom1 --$opt < $example 2>&1`;
   $output =~ s/mptopcom version.*?\n//s;
   open(my $outfile, ">$file.out");
   print $outfile $output;
   close($outfile);
   if(compare_results($file, $file.".out")){
      `mv $file.out $file`;
      print "ok.\n";
   } else {
      print "fail.\n";
      `mv $file.out $file.fail`;
   }
}

sub compare_results {
   my($file1, $file2) = @_;
   my $t1 = get_triangulations($file1);
   my $t2 = get_triangulations($file2);
   return $t1 == $t2;
}

sub get_triangulations {
   my($file) = @_;
   my $entire = `cat $file`;
   my @triangs = $entire =~ m/(\{\{.*\}\})/gm;
   my $result = new Set<Set<Set<Int>>>();
   foreach my $triang (@triangs){
      $triang =~ s/\{/[/g;
      $triang =~ s/\}/]/g;
      $result += new Set<Set<Int>>(eval $triang);
   }
   return $result;
}
