#!/usr/bin/perl
#
# ORXONOX nightly Revision Making utility
# for orxonox source and data updates.


# DEFINITIONS
my $SourceRepository = "http://svn.orxonox.net/orxonox/trunk";
my $DataRepository = "http://svn.orxonox.net/data/trunk";
my $ReleaseDir = "/var/www/orxonox/files/snapshots";
my $tmpDir = "/tmp/revmakeSrc";


# USED IN THIS SCRIPT
my $SOURCELastChangedVersion  = 0;
my $DataLastChangedVersion    = 0;
my $doUpdate                  = 0;
my $orxonoxVersion            = "";
my $orxonoxMakeFileName       = "";

##Function Stack ##
prepareEnvironment();
checkChanges();
if ($doUpdate == 0) { 
  die "Nothing to do. Already at newest Version\n"; }
gatherData();

exportToRelease();
compress();
moveToReleaseDir();

sendMail();
###################

#################################################################
# Creates a Temporary Directory for the Data                    #
#################################################################
sub prepareEnvironment()
{
  print "Preparing Environment\n";
  if (!-e $tmpDir){
    mkdir("$tmpDir");
  }
  if(!-e "$tmpDir/checkout") {
    mkdir("$tmpDir/checkout");
  }
  if(-e "$tmpDir/orxonox") {
    system("rm -rf $tmpDir/orxonox");
  }
  
  mkdir("$tmpDir/orxonox");
}

#################################################################
# Checks the Runtime and Data Repository for the Version Number #
#################################################################
sub checkChanges()
{
  my $change         = 1;

  $SourceLastChangedRevision = getRevisionNumber($SourceRepository);
  open(SOURCEFILES, "ls -1 $ReleaseDir/orxonox* |");
  while ($line = <SOURCEFILES>)
  {
   if ($line =~ /orxonox-.*-r$SourceLastChangedRevision.tar.bz2/) {
      $change = 0;
      $line =~ s/.*orxonox-(.*)-r$SourceLastChangedRevision.tar.bz2.*/\1/;
      $orxonoxVersion = $line;
      chomp($orxonoxVersion);
      print("not updating Source, because we are at revision $SourceLastChangedRevision\n");
      break;
    }
  }
  close ( SOURCEFILES );
  if ($change != 0) {
    $doUpdate += 1;
    print "located new Source-Revision Number $SourceLastChangedRevision\n";
  }


  $change = 1;
  $DataLastChangedRevision = getRevisionNumber($DataRepository);
  open(DATAFILES, "ls $ReleaseDir/orxonox-data* |");
  while ($line = <DATAFILES>)
  {
    if ($line =~ /orxonox-data-r$DataLastChangedRevision.tar.bz2/) {
      $change = 0;
      print("not updating Data, because we are at revision $DataLastChangedRevision\n");
      break;
    }
  }
  close ( DATAFILES );
  if ($change != 0) {
    $doUpdate += 2;
    print "located new Data-Revision Number $DataLastChangedRevision\n";
  }

  return ($doUpdate);
}

################################################################
# get last changed Revision Number (used by getRevisions())    #
################################################################
sub getRevisionNumber()
{
  my $repository = $_[0];
  my $retval = 0;
  open ( LOG, "svn log $repository --limit 1 |") or return $retval;
  while ($line = <LOG>)
  {
    if ($line =~ s/^r([1234567890]*).*/\1/)
    {
        $retval = $line;
	chomp $retval; 
        break;
    }
  }
  close ( LOG );
  return $retval;
}


################################################################
# 
################################################################
sub gatherData()
{
  checkoutRepos($SourceRepository, "$tmpDir/checkout/orxonox"); 
  checkoutRepos($DataRepository, "$tmpDir/checkout/data");
}

################################################################
# Checks out a repository from $_[1] to $_[2]                  #
# also makes some test, if the local Version is locked...      #
################################################################
sub checkoutRepos()
{
  my $repos = $_[0];
  my $destination = $_[1];
  my $CHECKOUT;
  my $line;
  my $done = 0;

  while ($done == 0)
  {
    open(CHECKOUT, "svn co $repos $destination 2>&1 |");
    while ($line = <CHECKOUT>)
    {
      $done = 1;
      print("$line");
      if ($line =~ /^svn:.* locked/)
      {
      	print "cleaning up $destination\n"; 
        system("svn cleanup $destination");
        $done = 0;
	break;
      }
    }
    close ( CHECKOUT );
  }
}

#############################################################
# RELEASE CREATION
#############################################################
sub exportToRelease()
{
  system("svn export $tmpDir/checkout/data $tmpDir/orxonox/data --force");
  system("svn export $tmpDir/checkout/orxonox $tmpDir/orxonox --force");
}


sub compress ()
{
  chdir("$tmpDir/orxonox/");

  if ($doUpdate == 1 || $doUpdate == 3)
  {
   ## executing configure, and let automake generate the tar-file
   print("Create Source Release\n");
   system("./autogen.sh");
   system("./configure");
   open(MAKE, "make dist-bzip2 |");
   while ($line = <MAKE>) {
     if ($line =~ s/.*orxonox-(.*).tar.bz2.*/\1/) {
       chomp($line);
       $orxonoxVersion = $line;
       $orxonoxMakeFileName = "orxonox-$orxonoxVersion.tar.bz2";
       print("Located VersionString: $orxonoxVersion\n");
     }
   }
   close ( MAKE );
  } 

  ## CREATE DATA...
  if ($doUpdate >= 2)
  {
   print("creating orxonox-data.tar.bz2 file\n");
   open(TAR, "tar cjvf $tmpDir/orxonox/orxonox-data.tar.bz2 data |");
   while($line = <TAR>)
   {
       print("$line");
   }
   close ( TAR );
  }
}


sub moveToReleaseDir()
{
  chdir($ReleaseDir);
  print("Moving the Files to their Destination\n");
  if ($doUpdate == 1 || $doUpdate == 3)
  {
   system("mv $tmpDir/orxonox/$orxonoxMakeFileName $ReleaseDir/orxonox-$orxonoxVersion-r$SourceLastChangedRevision.tar.bz2");
   if (-e "$ReleaseDir/orxonox-src-latest.tar.bz2") {
      system ("rm -f $ReleaseDir/orxonox-src-latest.tar.bz2");
   }
   print ("ln -sf orxonox-$orxonoxVersion-r$SourceLastChangedRevision.tar.bz2 $ReleaseDir/orxonox-src-latest.tar.bz2\n");
   system("ln -sf orxonox-$orxonoxVersion-r$SourceLastChangedRevision.tar.bz2 $ReleaseDir/orxonox-src-latest.tar.bz2");
  }
  
  if ($doUpdate >= 2)
  {
   system("mv $tmpDir/orxonox/orxonox-data.tar.bz2 $ReleaseDir/orxonox-data-r$DataLastChangedRevision.tar.bz2");
   if (-e "$ReleaseDir/orxonox-data-latest.tar.bz2") {
     system("rm -f $ReleaseDir/orxonox-data-latest.tar.bz2"); }
   print ("ln -sf orxonox-data-r$DataLastChangedRevision.tar.bz2 $ReleaseDir/orxonox-data-latest.tar.bz2\n");
   system("ln -sf orxonox-data-r$DataLastChangedRevision.tar.bz2 $ReleaseDir/orxonox-data-latest.tar.bz2");
  }
}


sub sendMail()
{
  my $sendmail = "/usr/sbin/sendmail -t";
  my $reply_to = "Reply-to: orxonox-dev\@mail.datacore.ch\n";
  my $subject  = "Subject: new orxonox-source/data generated: Version: $orxonoxVersion-$SourceLastChangedRevision, Data: r$DataLastChangedRevision\n";
  my $from     = "From: orxonox\@orxonox.ethz.ch\n";
  my $to       = "orxonox\@orxonox.ethz.ch\n";
  my $sendTo   = "To: orxonox-commit\@mail.datacore.ch\n";
  my $content  = "A new source/data version of orxonox has arrived: Version: r$orxonoxVersion-$SourceLastChangedRevision-d$DataLastChangedRevision\n" .
		 "------------------------------------------------------------------------------------\n\n" .
                 "You can download the source from: \n" .
                 "  http://www.orxonox.net/files/snapshots/orxonox-$orxonoxVersion-r$SourceLastChangedRevision.tar.bz2\n" .
		 "or the always valid substitution Link:\n" .
		 "  http://www.orxonox.net/files/snapshots/orxonox-src-latest.tar.bz2\n" .
		 " \n\n" .
		 " The Hardware-independant Data can be found either from: \n" .
		 " http://www.orxonox.net/files/snapshots/orxonox-data-r$DataLastChangedRevision.tar.bz2\n" .
		 " or as always from the valid substitution Link:\n" .
		 " http://www.orxonox.net/files/snapshots/orxonox-data-latest.tar.bz2\n" .
		 "-----------------------------------------------------------------------------------\n\n" .
		 "# # This is an automated Mail generated by the RevisionMaker # #\n" .
		 " #   Please report missing links to orxonox-dev\@mail.datacore.ch   #\n"  .
		 ".\n";
 
  open( SENDMAIL, "| $sendmail") or die "Cannot open $sendmail: $!";
  print SENDMAIL $sendTo;
  print SENDMAIL $from;
  print SENDMAIL $subject;
  print SENDMAIL $reply_to;
  print SENDMAIL "Content-type: text/plain\n\n";
  print SENDMAIL $content;
  close(SENDMAIL);  
}


