# this is no funky script, let's use strict and Carp
use strict;
use Carp;
use Data::Dumper;
use vars qw /$CONFIG $FILE/;
$CONFIG = undef;
$FILE = shift (@ARGV) or
    die "Usage: db2file.pl <filename>";

# let's parse install.conf to find out where MKDoc libraries
# are installed on the system
BEGIN
{
    $CONFIG = {};
    
    open FP, "<../install.conf" or die "Cannot read-open ../install.conf";
    while (my $string = <FP>)
    {
	chomp ($string);

	# if the line starts with a comment, then it's all a comment
	next if ($string =~ /^\#.*/);
	
        # has this line got comments?
        if ($string =~ /(?<!\\)\#/)
        {
            my ($key, $val, $cmt) = $string =~ /(.*?)\s+(.*?)\s+(.*)/;
            $val =~ s/\s+$//;
	    $CONFIG->{$key} = $val;
        }
        else
        {
            if ($string =~ /\S+(\s+)\S+/)
            {
                my ($key, $val) = $string =~ /(.*?)\s+(.*)/;
                $val =~ s/\s+$//;
		$CONFIG->{$key} = $val;
            }
            else
            {
                my $key = $string;
                my $val = 1;
		$CONFIG->{$key} = $val;
            }
        }
    }
    close FP;
    
    # unshift @INC to add MKDoc install dir
    unshift @INC, $CONFIG->{MKDOC_DIR};
}


# try to import required modules
eval
{
    use lib::Config;
    use lib::Template;
    use lib::Exception;
    use flo::Category;
    use lib::Config;
    use lib::sql::type::ALL;
    use lib::sql::Table;
    use flo::IndexedTable;
};
die $@ if (defined $@ and $@);

# finally (!), let us do the job
main();

sub main
{
    # first of all, we need to load the database state
  lib::sql::Table->load_state ('../su');
    
    # let's eval the file to import database
    my $VAR1 = undef;
    open FP, "<$FILE" or
	die "Cannot read-open $FILE";
    my $data_dump = join '', <FP>;
    close FP;
    eval $data_dump;
    my $database = $VAR1;
    
    print "Dropping MySQL tables...\n";
    # time to drop all tables from MySQL... brrr
    foreach my $table_name (keys %{$lib::sql::Table::DATABASE})
    {
	my $table = lib::sql::Table->table ($table_name);
	eval '$table->drop;';
	carp $@ if $@;
    }
    
    print "Removing def files...\n";
    # now we need to remove all the def files from the su directory
    opendir DD, "../su" or
	croak "Cannot open dir su";
    foreach (grep /\.def$/, readdir (DD)) { unlink "../su/" . $_ or carp "Cannot unlink ../su/$_" }
    closedir DD;
    
    # we def tables are gone, let's kill the objects as well
    print "Killing table objects...\n";
    $lib::sql::Table::DATABASE = {};
    
    # try to eval the schema.pl to instanciate the table objects
    print "Revaling table objects...\n";
    open FP, "<../schema.pl" or
	die "Cannot read-open ../schema.pl";
    
    my $data = join '', <FP>;
    close FP;
    eval $data;
    croak $@ if ($@);
    
    # write the new def files
    print "Writing new def files...\n";
  lib::sql::Table->save_state ('../su');
    
    # now re-create all the tables 
    print "Creating tables...\n";
    foreach my $table_name (keys %{$lib::sql::Table::DATABASE})
    {
	my $table = lib::sql::Table->table ($table_name);
	eval '$table->create;';
	err ($@) if $@;
    }
    
    # re-insert objects into their respective tables
    print "Reinsert data...\n";
    foreach my $table_name (keys %{$database})
    {
	my $table = lib::sql::Table->table ($table_name) || next;
        bless $table, "lib::sql::Table"
	    if (ref $table eq "flo::Category");
	print ref $table, "\n";
	
	foreach my $record (@{$database->{$table_name}})
	{
	    eval '$table->insert ($record);';
            err ($@) if $@;
	}
    }
}


sub err
{
    my $err = shift;
    if (ref $err) { carp $err->{code} . ' : ' . $err->{info} }
    else          { carp $err }
}

1;