#!/usr/bin/perl

use Cwd;
use strict;


#
# This Perl script gathers goo from the Omino After Effects Suite build
# and shovels it into a generated web site. 
# it's all very ad-hoc, I assure you.
#


# -------------------------------------
# mp_new_opts(@ARGV)
#
# Given a list of arguments, return
# a hash where the keys and values
# are taken from those arguments of
# the form "--key=value". The hyphens
# disappear from the key name.
#
# A command line switch of "--key"
# is equivalent to "--key=_".
#
# a special key named _argc contains
# a count of non-dash-dash arguments,
# and they are in the hash as {0}, {1},
# and so on.
#
# |     in: array of arguments (such as @ARGV)
# |
# | return: reference to be accesed by mp_get_opt
# |
# | (no dispose routine needed)
# |

sub mp_new_opts
  {
  my $arg;
  my $argVal;
  my $argc;
  my %hash;

  $argc = 0;


  while($arg = shift)
    {
    if($arg =~ /^--/)
      {
      if($arg =~ /^--(.*)\=(.*)$/)
        {
        $arg = $1;
        $argVal = $2;
        }
      elsif($arg=~ /^--(.*)$/)
        {
        $arg = $1;
        $argVal = "_";   # a true-but-zero value
        }

      $hash{$arg} = $argVal;
      }
    else
      {
      $hash{$argc++} = $arg;
      }
    }

  $hash{_argc} = $argc;

  return \%hash;
  }




# -------------------------------
# mp_get_opt(opts_ref, switch_name, default_value [, must_be_number])
#
# Look at a hash as returned by parseArgs, and
# give the value of the switch, or the default_value
# if it was not specified in the command line.
#
# |     in: opts_ref       -- reference from mp_new_opts
# |         switch_name    -- name of --option to check
# |         default_value  -- value to return if it wasnt in the args
# |         must_be_number -- optional boolean to force numeric interpretation
# |

sub mp_get_opt
  {
  my $opts_ref = shift;
  my $switch_name = shift;
  my $default_value = shift;
  my $must_be_number = shift;

  my $switch_value;

  $switch_value = $$opts_ref{$switch_name};
  $switch_value = $default_value if ($switch_value eq "");
  $switch_value *= 1 if ($must_be_number);

  return $switch_value;
  }


# +-------------------------
# | mp_read_file(filename[,error_ref])
# |
# | returns the complete file contents
# |
# |
# |     in: filename -- name (path) of file to read
# |
# | return: one long string with the whole file, or
# |         empty string if no such file or empty file.
# |
# |         (use Perl's -e if you really really care whether
# |         the file was there...)
# |

sub mp_read_file
  {
  my ($filename,$error_out) = (@_);
  my $bunch;
  my $file_contents;
  my $did;

  # (return error if ref provided)

  if($error_out)
    {
    $$error_out = (-f $filename) ? 0 : -1;
    }

  # (read the whole file, if present. else "")

  if(open(FILE,$filename))
    {
    binmode FILE;    # Bite me, Windows! --dvb
    while(read(FILE,$bunch,32000))
      {
      $file_contents .= $bunch;
      }
    close FILE;
    }

  return $file_contents;
  }

# -----------------------
# mp_write_file(filename,contents)
#
# creates new file and writes entire
# file contents. Return "ok" if so,
# or "" if not.
#
# |
# |     in: filename -- name of file to create (or replace)
# |         contents -- string of all the bytes to put into file
# |
# | return: 0 for success, <0 for error
# |

sub mp_write_file($$)
  {
  my ($filename,$contents) = (@_);

  my $did;

  #
  # If filename is "", print it to stdout
  # and that is all.
  #

  if($filename eq "")
    {
    print $contents;
    return "";
    }

  #
  # Delete existing file, if any.
  #

  unlink ($filename) if(-e $filename);

  $did = open(FILE,">$filename");
  if($did)
    {
    binmode FILE;    # Bite me, Windows! --dvb
    $did = print FILE $contents;
    close FILE;
    return $did ? 0 : -1;
    }

  return -1;
  }

sub mp_date_time
{
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdet) = localtime(time);
    $mon++;
    $year += 1900;
    my $d = sprintf("%04d.%02d.%02d",$year,$mon,$mday);
    my $t = sprintf("%02d:%02d:%02d",$hour,$min,$sec);

    return "$d $t";
}

sub E(@)
{
    print mp_date_time()," ",@_,"\n";
}

sub doSystem($)
{
    my ($cmd) = (@_);
    E("doing: $cmd");
    # danger and such.
    my $code = system($cmd);
    if($code != 0)
    {
        print "---------------------\n";
        print "ERROR: $code\n";
        print "doing:\n";
        print "  $cmd\n";
        print "---------------------\n";
    }
}

# grep a file for #defines, return in hash
sub getDefines($)
{
    my $file = shift;
    my %result;
	open F,$file or die "could not read $file";
	
	my $line;
	my $file;
	while($line = <F>)
		{
		if($line =~ /^(.*?)[\n\r]*$/)
		{
			$line = $1;
		}

		if($line =~ /^(#define) ([^ ]+) (.+)$/)
			{
			my $def = $1;
			my $name = $2;
			my $value = $3;
            if($value =~ /^\"(.*?)\"$/)
            {
                $value = $1;
            }
            $result{$name} = $value;
            }
				
		}

	close F;
    return %result;
	}

sub fixupFile($%)
{
    my ($filename,$fixersRef) = (@_);
    my $s = mp_read_file($filename);

    foreach my $key (sort(keys(%$fixersRef)))
    {
        my $value = $$fixersRef{$key};
        print "$key ==> $value\n";
        $s =~ s/--$key--/$value/gs;
    }

    mp_write_file($filename,$s);
}

sub buildZip($@$$$$$)
{
    my ($SRC,$filesList,$majorVersion,$minorVersion,$buildNumber,$suffix,$compressionKind) = (@_);

    my $TEMP_ZIP_SPOT = "$SRC/build/temp";
    print "TEMP_ZIP_SPOT = $TEMP_ZIP_SPOT\n";
    my $NAME = "ominoSuiteV${majorVersion}_${minorVersion}_${buildNumber}_${suffix}";
    my $ZIP = "$NAME.${compressionKind}";
    my $PATH = "$TEMP_ZIP_SPOT/$NAME";
    my $ZIPP = "$TEMP_ZIP_SPOT/$NAME.${compressionKind}";

    doSystem("rm -rf $TEMP_ZIP_SPOT");
    doSystem("mkdir $TEMP_ZIP_SPOT");
    doSystem("mkdir $PATH");
    foreach my $file (sort(@$filesList))
    {
        doSystem("cp -r $file $PATH");
    }
    if($compressionKind eq "zip")
    {
        my $oldDir = cwd();
        chdir($TEMP_ZIP_SPOT);
        doSystem("zip -r $ZIP $NAME");
        chdir($oldDir);
    }
    else
    {
        my $oldDir = cwd();
        chdir($TEMP_ZIP_SPOT);
        doSystem("tar czvf $ZIP $NAME");
        chdir($oldDir);
    }
    return $ZIPP;
}

sub buildWindowsZip($$$$)
{
    my ($SRC,$majorVersion,$minorVersion,$buildNumber) = (@_);
    my $WINDROP = "$SRC/omino_suite_for_windows/*.aex";
    my $bendersDir = "$SRC/benders";
    my @winParts = (
        "$bendersDir/omino_colorizer.pbk",
        "$bendersDir/omino_glass.pbk",
        "$bendersDir/omino_lines.pbk",
        "$bendersDir/omino_spindala.pbk",
        "$bendersDir/omino_staragon.pbk"
        );
    my $result = buildZip($SRC,\@winParts,$majorVersion,$minorVersion,$buildNumber,"win","zip");
    return $result;
}

sub buildMacTar($$$$)
{
    my ($SRC,$majorVersion,$minorVersion,$buildNumber) = (@_);
    my $macPluginsDir = "$SRC/build";
    my $bendersDir = "$SRC/benders";
    my @macParts = (
        "$macPluginsDir/omino_diffusion.plugin",
        "$macPluginsDir/omino_feedback.plugin",
        "$macPluginsDir/omino_halftone.plugin",
        "$macPluginsDir/omino_kaleidoscope.plugin",
        "$macPluginsDir/omino_sphere_map.plugin",
        "$macPluginsDir/omino_squares.plugin",
        "$macPluginsDir/omino_snake.plugin",

        "$bendersDir/omino_colorizer.pbk",
        "$bendersDir/omino_glass.pbk",
        "$bendersDir/omino_lines.pbk",
        "$bendersDir/omino_spindala.pbk",
        "$bendersDir/omino_staragon.pbk"
        );

    my $result = buildZip($SRC,\@macParts,$majorVersion,$minorVersion,$buildNumber,"mac","tgz");
    return $result;
}

sub getName($)
{
    my $path = shift;
    if($path =~ /^.*\/(.*)$/)
    {
        $path = $1;
    }
    return $path;
}

sub buildReleaseSite($)
{
    my $SRC = shift;

    my $WEBSRC = "$SRC/websrc";

    my $VERSIONFILE = "$SRC/shared/dvb/omino_suite_version.h";

    my $VISUALREPORT = "tests/testOutput/allTestsVisualReport.png";

    my %versionStuff = getDefines($VERSIONFILE);
    my $majorVersion = $versionStuff{PLUGIN_MAJOR_VERSION};
    my $minorVersion = $versionStuff{PLUGIN_MINOR_VERSION};
    my $buildNumber = $versionStuff{BUILD_NUMBER};
    my $buildDate = $versionStuff{k_version_date};

    my $DESTFOLDER = "$SRC/build_site";
    my $DESTNAME = "ominoAeSuite_${majorVersion}_${minorVersion}_${buildNumber}";
    my $DEST = "$DESTFOLDER/$DESTNAME";
    my $DESTBIN = "$DEST/bin";

    # no space in path or kill ya

    doSystem("rm -rf $DEST");
    doSystem("mkdir -p $DEST");
    doSystem("cp -rf $WEBSRC/* $DEST");
    doSystem("cp $VISUALREPORT $DEST/img");
    doSystem("mkdir $DESTBIN");
    my $MACBALL = buildMacTar($SRC,$majorVersion,$minorVersion,$buildNumber);
    my $MACBALLNAME = getName($MACBALL);
    doSystem("cp $MACBALL $DESTBIN");
    my $WINBALL = buildWindowsZip($SRC,$majorVersion,$minorVersion,$buildNumber);
    my $WINBALLNAME = getName($WINBALL);
    doSystem("cp $WINBALL $DESTBIN");
    doSystem("rm -rf $DEST/.svn");
    doSystem("rm -rf $DEST/img/.svn");

    # and patch up the html
 
    my %fixers;
    $fixers{date} = mp_date_time();
    $fixers{macdownload} = $MACBALLNAME;
    $fixers{windownload} = $WINBALLNAME;
    $fixers{majorVersion} = $majorVersion;
    $fixers{minorVersion} = $minorVersion;
    $fixers{buildNumber} = $buildNumber;
    $fixers{buildDate} = $buildDate;

    fixupFile("$DEST/index.html",\%fixers);


    # and make a tgz for upload...
    doSystem("tar czvf $DEST.tgz -C $DESTFOLDER $DESTNAME");
}

sub main()
{
    # assumes we are run with cwd=source tree root. sheesh.
    my $src = cwd();
    buildReleaseSite($src);
}

main();

# end of file
