#!/bin/perl

# This program adds residuals to files which don't have them (or forces a recompute of all residuals
# if called with --force).

use strict;
use warnings;
use File::Slurp;
use File::Path;
use Data::Dumper;
use Getopt::Long;

# We start by loading the database.

my $force = '';
GetOptions ( 'force' => \$force);

my $DBFILE = read_file('KnotDB.pl');
my %knots;
eval($DBFILE);

my %wknots = %knots;

my $numkeys = keys ( %wknots );
my $key;

if ( $force ) {

    print "We have $numkeys entries in the database. Recomputing residuals for everything...\n";

} else {

    print "We have $numkeys entries in the original database. Looking for files without residuals...\n";
    
# first, a pass to remove files with residuals from the hash
    
    foreach $key ( sort(keys %wknots) ) {
	
	if (defined($wknots{$key}{residual})) {
	    
	    delete $wknots{$key};
	    
	}
	
    }
    
    $numkeys = keys ( %wknots );
    print "There seem to be $numkeys knot types in the database without residuals. Generating residuals now.\n";

}

chdir "./vects" or die "Couldn't change to ./vects: $_";

my $filename;
my $residual;

foreach $key ( keys %wknots ) {

    if ($key =~ /vect/) { # If the key contains "vect", it is a filename
	$filename = $key;
    } else {
	$filename = $wknots{$key}{filename};
    }

    print "Processing knot type $key, represented by filename $filename.\n";

    if (defined $knots{$key}{residual}) {

	print "Previous residual $knots{$key}{residual}.\n";

    }

    $residual = undef;

    print "Running residual.pl . . .\n";
    open(RESIDUAL,"residual.pl $filename | ");
    while (<RESIDUAL>) {
	if ($_ =~ m/Residual: (\S+)/) { 
	    $residual = $1;
        }
    }
    close RESIDUAL;

    $knots{$key}{residual} = $residual;
    print "Computed residual = $residual.\n\n";

}

chdir("..") or die("Couldn't change back out of ./vects");

print "Writing updated database...\n";
rename "KnotDB.pl","KnotDB.bak.pl" or die("Couldn't rename the old knot database.\n");

open(KNOTDB,'>KnotDB.pl') or die "Unable to create Knot database.";
print KNOTDB Data::Dumper->Dump([\%knots],['*knots']),"\n";
close KNOTDB;

