#!/usr/bin/perl

#
# build obo file if needed
#

use strict;
use Time::Local;

use constant OBO2FLAT => "/share/go/bin/oboedit/current/obo2flat";
use constant LOGFILE => "/share/go/logs/build_flatfile.log";

my %files = (FUNC => "/share/ftp/pub/go/ontology/function.ontology",
	     COMP => "/share/ftp/pub/go/ontology/component.ontology",
	     PROC => "/share/ftp/pub/go/ontology/process.ontology",
	     DEF  => "/share/ftp/pub/go/ontology/GO.defs",
	     OBO  => "/share/ftp/pub/go/ontology/gene_ontology.obo",
	     );

my %filetimes = ();

print STDERR "Starting Monthly build_flatfile.pl script.  Please check log file /share/go/logs/build_flatfile.log for details.\n";

open (LOG, ">>" . LOGFILE) || die "Cannot open log file, " . LOGFILE . "\n";

#
# select LOGFILE so that flat2obo and cvs output is captured
#
select (LOG); $| = 1;

print "---------------\n";
print scalar localtime, "\n";
print "---------------\n\n";

foreach my $file (keys %files) {
    #  index to the array from stat() in next line:
    #  $dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks
    #
    #  we'll use the "last modify time" of the file, index 9
    #
    my ( @stats ) = stat $files{$file};

    $filetimes{$file} = @stats[9];
}

my $obotime = timelocal(localtime($filetimes{'OBO'}));

my $rebuild = 0;

foreach my $file (keys %files) {
    if ($file ne "OBO") {
	my $filetime = timelocal(localtime($filetimes{$file}));

	if ($filetime == 0) {
	    die "Required file, $files{$file}, is missing!\n";
	}

	if ($filetime > $obotime) {
	    print "NEWER\t$files{$file} than OBO\n";
	    # flat files will be newer than OBO because of this script
	    warn "Someone updated a flat file, " . $files{$file} . "\n";
	    $rebuild = 0;
	} else {
	    print "OLDER\t$files{$file} than OBO\n";
	    # rebuild flat files is OBO file is newer
	    #  that means the OBO file has been updated by a curator or editor
	    $rebuild = 1;
	}
    }
}

#
# if OBO file is newer than one of the three ontology files or the definition file
# the OBO file needs to be rebuilt.
#

if ($rebuild) {
    print "\nRebuild of flat files starting.\n";

    my $dstr = `date +%Y%m%d`;
    chomp $dstr;

    # clone LOG filehandler to STDERR
    open (STDOUT, ">&LOG") || die "Cannot dup LOG filehander for STDOUT: $!\n";
    open (STDERR, ">&LOG") || die "Cannot dup LOG filehander for STDERR: $!\n";

    # rebuild obo file
    my $cmd = OBO2FLAT . " --gopresets $files{PROC} $files{COMP} $files{FUNC} $files{DEF} -symbol negatively_regulates \'-\' -symbol positively_regulates \'+\' -symbol regulates \'&\' $files{OBO} < /dev/null";

    my $status = system($cmd);

    print "OBO2FLAT returned status = $status\n";

    if ($status) { die "FATAL: flat2obo execution failed: $!\n"; }

    # commit updated obo file
    my $cmd = "/usr/bin/csh -c 'unlimit; /tools/gnu/bin/cvs -d /share/go/cvs commit -m $dstr $files{PROC} $files{COMP} $files{FUNC} $files{DEF}'";

    my $status = system($cmd);

    if ($status) { die "FATAL: cvs commit failed: $!\n"; }

} else {
    print "Update exiting, flat files are up-to-date\n";
}

print "\n";

close LOG;

exit 0;

