#!/usr/bin/perl

#use strict;
use Shell qw(mkdirhier);

## ----------------------------------------------------------------------

sub usage {
  my $ME     = $0;
  $ME        =~ s/.*\///;    # only the basename

  print "\n\tusage:  $ME\n";
  print "\t\t\t-t zimpl-tbl-file    (default: )\n";
  print "\t\t\t-l log-file          (default: solver.log)\n";
  print "\t\t\t-s edges-sol-file    (default: edgecap.sol)\n";
  print "\t\t\t--cplex              (solve with cplex not with scip)\n";
  exit;
}

## ----------------------------------------------------------------------
##    forward declarations
## ----------------------------------------------------------------------

sub check_parameters(@);

sub read_tbl_file($);
sub read_log_file($);


## ----------------------------------------------------------------------
##    variables
## ----------------------------------------------------------------------

# -------------------------------------------------------------------------
#    constants
# -------------------------------------------------------------------------

use constant TRUE         => 1;
use constant FALSE        => 0;

## ----------------------------------------------------------------------
##    main method
## ----------------------------------------------------------------------

my ( $outdir, $tblfile, $logfile, $edgesolfile )
  = check_parameters( @ARGV );

my %namemap = read_tbl_file($tblfile);
my %support = read_log_file($logfile);


## ----------------------------------------------------------------------
##
##    writing to OUTDIR
##
## ----------------------------------------------------------------------

chdir $outdir;

## ----------------------------------------------------------------------
##    write sol-file EDGES
## ----------------------------------------------------------------------

if(  $edgesolfile ne "nofile" )
{
#    message( "write $edgesolfile" );
   open( EDGES, "> $edgesolfile" ) or die("$edgesolfile: $!\n");

   ## write header
   print EDGES sprintf( "%-15s %-15s %-10s\n", "# source", "target", "capacity" );

   foreach my $key (keys %support) {

   ## we need an x variable here !!!!!
     if( $key =~ m/^x/ ) {

       my ( $source, $target ) = split /\$/, $namemap{$key};
       print EDGES sprintf( "S %-15s %-15s %.2f\n", $source, $target, $support{$key} );
     }
   }
   message("  Wrote a new solution to $edgesolfile ");
}



exit(0);


## ----------------------------------------------------------------------
##
##    read tbl-file
##
## ----------------------------------------------------------------------

sub read_tbl_file($) {

  my $tblfile = shift;
  my %namemap = ();

#   message( "called read_tbl_file: $tblfile" );

  open( TBLFILE, $tblfile ) or die ("$tblfile: $!\n");

  while (<TBLFILE>) {

    if( /^zimpl\s+v\s/ ) { # it's a ZIMPL variable

      my $line = $_;
      my ( $zimpl, $type, $cnt, $short_name, $long_name ) = split /\s+/, $line;

      # remove prefix upto "$" and postfix "\""
      $long_name  = substr($long_name,3,length($long_name)-4);

      $namemap{$short_name} = $long_name;
    }
  }

  return %namemap;
}

## ----------------------------------------------------------------------
##
##    read log-file
##
## ----------------------------------------------------------------------

sub read_log_file($) {

  my $logfile = shift;
  my %value_of = ();

  open( LOGFILE, $logfile ) or die ("logfile: $!\n");

  my $solution_line = FALSE;

  while(<LOGFILE>) { # read all lines

    my $line = $_;
    if( ($solver == "cplex" && $line =~ m/Variable Name/) ||
        ($solver == "scip"  && $line =~ m/^objective value:/)   ) {
      %value_of = ();
      $solution_line = TRUE;
    }
    elsif( ($solver == "cplex" && $line =~ m/All other variables in the range/) ||
           ($solver == "scip" && $line =~ m/^Statistics/) ) {
      $solution_line = FALSE;
    }
    elsif( ($solver == "cplex" && $line =~ m/No integer feasible solution exists/ ) ||
           ($solver == "scip" && $line =~ m/^no solution available/ ) ) {
      warning( " .............. no integer feasible solution ................." );
      warning( " .............. cannot construct solution ................." );
      exit 1;
    }

    if( $solution_line eq TRUE ) {
#       print $line;
      my ( $var, $value ) = split /\s+/, $line;
#       print $line . " --- " . $var . "\t" . $value . "\n";
      $value_of{$var} = $value;
    }
  }

  close LOGFILE;

  return %value_of;
}

## ----------------------------------------------------------------------
##
##    check parameters
##
## ----------------------------------------------------------------------

sub check_parameters (@) {

  scalar @_ <= 16 or die usage();

  my $outdir         = ".";
  my $logfile        = "solver.log";
  my $tblfile        = "";
  my $edgesolfile    = "solution.sol";
  my $solver         = "scip";

  my $i = 0;
  my $n = scalar @_;

  while( $i < $n ) {

       if( $_[$i] eq "-t"  ) { $i++; $tblfile              = glob($_[$i]); }
    elsif( $_[$i] eq "-l"  ) { $i++; $logfile              = glob($_[$i]); }
    elsif( $_[$i] eq "-s"  ) { $i++; $edgesolfile          = glob($_[$i]); }
    elsif( $_[$i] eq "--cplex"  ) {$solver="cplex"}
    else { error( "unknown parameter $_[$i]" ); }
    $i++;
  }

  -f $tblfile        or error( "unknown TBL-file $tblfile");
  -f $logfile        or error( "unknown LOG-file $logfile");
#   -d $outdir or message("mkdirhier $outdir"), mkdirhier "$outdir";

  return ( $outdir, $tblfile, $logfile, $edgesolfile );
}


## ----------------------------------------------------------------------
##
##    helpers
##
## ----------------------------------------------------------------------


sub message($)  { print "$_[0]\n"; }
# sub message($)  { }
sub warning($)  { print "\nWARNING: $_[0]\n\n"; }
sub error($)    { print "\nERROR: $_[0]\n\n"; }
sub myassert(@) { if( $_[0] == 0 ) { error( "assert $_[1] failed" ); } }


## ----------------------------------------------------------------------
##    end
## ----------------------------------------------------------------------
