#!/tools/perl/current/bin/perl
########################################################################
#        Script Name:      run-obodiff.pl
#        Author:           Mike Cherry (from Shuai Weng's goCheck.pl)
#        Date:             December 2004
#        Description: This script is used to check the daily changes 
#                     of gene_ontology_write.obo file and run the OBO-Edit 
#                     script "obodiff" to record changes to the GO-DIFF
#                     mailing list.
#          
#        Procedures:       
#        1.  remove files under today's dir
#        2.  cvs check out the files
#        4.  run obodiff
#        5.  copy today's ontology files to yesterday dir        
#                 
########################################################################

use strict;

########################################################################
my ($exitcode, $DIR, $SAVEDIR, $lockfile, $mailtoaddr, $logfile);
my ($oldfiles, $oldrmfailed, $newfiles, $oldversion, $newversion);
my ($difffile, $tmpdifffile, $month, $day, $year, $mailsubj);
my (%count);
########################################################################
$| = 1;
########################################################################

###### set global variables
&setGlobalVariables;

###### do some file checks and remove the ontology files under today's dir
&doPreCheckAndCleanUp; 

###### cvs check out the current ontology files
&cvsCheckOut;

###### run obodiff
&runDiff;

###### check the diff output and send diff to go-diff group
&mailDiff;

###### save today's files to yesterday dir remove the tmp files
&saveFilesAndCleanUp;

exit $exitcode;

########################################################################
sub setGlobalVariables {
########################################################################

    $DIR = "/share/go/cvs";
    $SAVEDIR = "/share/go/saved";

    $lockfile = "$SAVEDIR/run-obodiff.lock";

    $oldfiles = "$SAVEDIR/yesterday/go";
    $oldrmfailed = "$SAVEDIR/yesterday/obodiff.rm.failed";

    $newfiles = "$SAVEDIR/today/go";
    $difffile = "$SAVEDIR/obodiff-tmp.out";

    $exitcode = 0;
    $oldversion = "";
    $newversion = "";

    ($month, $day, $year)=(localtime())[4,3,5];
    $year += 1900;
    $month++;

    $month = "0$month" if ($month < 10);
    $day = "0$day" if ($day < 10);

    $mailsubj = "GO update $month/$day/$year";
    $mailtoaddr = "go-diff\@genome.stanford.edu";

    $logfile = "$SAVEDIR/logs/run-obodiff.log.${year}${month}${day}";

}

########################################################################
sub cvsCheckOut {
########################################################################

    ### check out the go related files from cvs control
    my @command = ("cd $SAVEDIR/today && /tools/gnu/bin/cvs -d $DIR co go/ontology/editors/gene_ontology_write.obo");
    my $err = system("@command");
    if ($err) {
	unlink($lockfile);
	die "run-obodiff: cvs update failed: $!\n";
    }

}

########################################################################
sub runDiff {
########################################################################

    # required Java 1.4 so for now this script must be run on DOUGH (or YEAST)
    my $err = system ("/share/go/bin/oboedit/current/obodiff $oldfiles/ontology/editors/gene_ontology_write.obo $newfiles/ontology/editors/gene_ontology_write.obo > $difffile");

    if (!open(OLDOBO, "$oldfiles/ontology/editors/gene_ontology_write.obo")) {
	unlink($lockfile);
	die "Cannot open old OBO file: $!\n";
    }

    while ( <OLDOBO> ) {
	if (/\$Revision: (\d+\.\d+) /) {
	    $oldversion = $1;
	}
    }
    close (OLDOBO);

    if (!open(NEWOBO, "$newfiles/ontology/editors/gene_ontology_write.obo")) {
	unlink($lockfile);
	die "Cannot open new OBO file: $!\n";
    }

    while ( <NEWOBO> ) {
	if (/\$Revision: (\d+\.\d+) /) {
	    $newversion = $1;
	}
    }
    close (NEWOBO);

    ### no change if diffing the same version
    if ($oldversion == $newversion) {
	unlink($lockfile);
	die "Version $oldversion by $newversion -- same version -- exiting\n";
    }

    ### delete diff file if there is no change 
    if (-z "$difffile") {
	unlink($difffile);
	unlink($lockfile);
	die "Version $oldversion by $newversion -- no change today -- exiting\n";
    }
}

########################################################################
sub mailDiff {
########################################################################

    my $openMAIL = 0;

    if (!open (MAIL, "|/usr/bin/mailx -s \'$mailsubj\' $mailtoaddr")) {
	unlink($lockfile);
	die "Cannot open pipe to mailx: $!\n";
    }
	
    if (!open (LOG, ">$logfile")) {
	unlink($lockfile);
	die "Cannot open $logfile: $!\n";
    }

    $openMAIL = 1;

    print MAIL "OBODIFF of gene_ontology_write.obo version $oldversion by $newversion\n\n";
    print LOG "OBODIFF of gene_ontology_write.obo version $oldversion by $newversion\n\n";

    if (!open (DIFFTXT, "$difffile")) {
	unlink($lockfile);
	die "Cannot open $difffile for LOG file: $!\n";
    }

    while ( <DIFFTXT> ) {
	next if (/MEMSETTING/);

	print MAIL "$_";
	print LOG "$_";

    }

    close(LOG);
    close(MAIL);

    unlink($difffile);

}

########################################################################
sub doPreCheckAndCleanUp {
########################################################################

    ### check if running as valid user
    if ((getpwuid($>))[0] ne "gocvs") {
	die "run-obodiff.pl: must be run by gocvs user\n";
    }

    ### check if the lockfile exists 
    ### if yes, exit; otherwise create lockfile
    if (-e $lockfile) {
	die "run-obodiff: lock file exists ($lockfile)! (previous run-obodiff still running?)\n";
    } 
    else {
	if (!open(LOCK, ">$lockfile")) {
	    die "run-obodiff: can't create lock file!\n";
	} 
	else {
	    close(LOCK);
	}
    }

    ### check if old-go-files' dir exists
    if (! -d $oldfiles) {
	unlink($lockfile);
	die "run-obodiff: $oldfiles doesn't exist!\n";
    }

    ### check if new-go-files' dir exists
    if (! -d $newfiles) {
	unlink($lockfile);
	die "run-obodiff: $newfiles doesn't exist!\n";
    }

    if (-d $oldrmfailed) {
	# current old files exist, go ahead and delete the tmp dir
	my $err = system("/bin/rm -rf $oldrmfailed");
	if ($err) {
	    unlink($lockfile);
	    die "run-obodiff: $oldrmfailed should be removed\n";
	}
    }

    ######## remove obo file before check out
    my $err = system("/bin/rm -f $newfiles/ontology/editors/gene_ontology_write.obo");
    if ($err) {
	unlink($lockfile);
	die "run-obodiff: $newfiles/ontology/editors/gene_ontology_write.obo could not be removed\n";
    }
    
}

########################################################################
sub saveFilesAndCleanUp {
########################################################################
    # remove yesterday/go files then copy today/go files
    my $err = system("/bin/rm -rf $oldfiles");
    if ($err) {
	print STDERR "run-obodiff: rm of old files failed:$!\n";
	
	### If we don't do this, we may compare new files with an
	### incomplete set of old files. 
	### Hopefully this rename will succeed.
	$err = system("/bin/mv -f $oldfiles $oldrmfailed");
	if ($err) {
	    print STDERR "run-obodiff: move $oldfiles to $oldrmfailed failed: $!\n";
	}
	$exitcode = 1;
    }
    else {
	my $err = system("/bin/cp -rp $newfiles $oldfiles");
	if ($err) {
	    print STDERR "run-obodiff: copy of $newfiles to $oldfiles failed:$!\n";
	    $exitcode = 1;
	}
	$exitcode = 0;
    }
    unlink($lockfile);
}

########################################################################
########################################################################

