#!/usr/bin/perl -w

########################################################
# package version = major, minor1, minor2, release
# $3 destinatin volume
# $0 this file path
my $TARGET_VOLUME	= $ARGV[0];
my $PACKAGE_VERSION_FILE    = "release_version";
my $INSTALLED_SERVER	    = "$TARGET_VOLUME"."/usr/sbin/QuickTimeStreamingServer";
my $INSTALLED_OS_VERS		= "$TARGET_VOLUME"."/System/Library/CoreServices/SystemVersion.plist";
my $REQUIRED_OS_VERS		= "10.1.0";
my $THIS_FILE_PATH          = $0;
my $THIS_PACKGE_VERSION     = GetThisVersion( $THIS_FILE_PATH );
my $INSTALLED_VERSION       = GetInstalledVersion( $INSTALLED_SERVER );
my $THIS_DIR                = $0;
$THIS_DIR =~ s/[^\/]*$//;
my $ERROR_STRINGS           = $THIS_DIR . "English.lproj/VolumeCheck.strings";
my $RESULT                  = 96;
########################################################

#exit 96; stop install with default message "This software cannot be installed. reason unknown..."
#exit 112; stop install with error string 16
#exit 113; stop install with error string 17
#exit 0; ok


#  only install on OS X volume
if ( SystemVersionPlistCheck ( $INSTALLED_OS_VERS, $REQUIRED_OS_VERS, "<" ) )
{
    if ( -e $ERROR_STRINGS )
    {   #there are localized error strings so use them
        $RESULT = 113;
    }

    exit ($RESULT);
}

# make sure we don't stomp a newer version
if ( ReleaseVersCheck( $THIS_PACKGE_VERSION , "<", $INSTALLED_VERSION ) )
{
    if ( -e $ERROR_STRINGS )
    {  #there are localized error strings so use them
       $RESULT = 112;
    }

    exit ($RESULT);
}

exit 0;

#####

sub SystemVersionPlistCheck
{
     my $path            = $_[0];
     my $version         = $_[1];
     my $operator        = $_[2];

     if (!$operator)
     {
         $operator = "==";
     }

     my $oldSeperator = $/;
     $/ = \0;

     open( PLIST, "$path") || do {
         return 1;
     };

     $plistData = <PLIST>;
     $plistData =~ /<dict>(.*?)<\/dict>/gis;

     @items = split(/<key>/, $plistData);

     shift @items;
     foreach $item (@items) {
         $item =~ /(.*?)<\/key>.*?<string>(.*?)<\/string>/gis;
         $versiondata{ $1 } = $2;
     }

     close(PLIST);

     $/ = $oldSeperator;

     @cfBundleVersionArray = split(/\./, $versiondata{ProductVersion});
     for ($i = 0; $i < 3; $i++) {
         if(!$cfBundleVersionArray[$i]) {
             $cfBundleVersionArray[$i] = '0';
         }
     }

     @versionArray = split(/\./, $version);

     my $actualVersion;

     for ($i = 0; $i < 3; $i++) {
         if (($cfBundleVersionArray[$i] != $versionArray[$i]) or ($i == 2)) {

             $actualVersion = $cfBundleVersionArray[$i];
             $version = $versionArray[$i];

             last;
         }
     }

     my $expression = '$actualVersion ' . $operator . ' $version';

     if( eval ($expression) )
     {
         return 1;
     }
     else
     {
         return 0;
     }

}

###
# args: file path for this script 
sub GetThisVersion
{ 
    my $path  =     $_[0];

    # strip of the file name from the path and add the version file name to it
    $path =~ s/[^\/]*$//;
    $path =  $path . $PACKAGE_VERSION_FILE;

    # default behavior for missing release_version file is to not install over existing server
    my $result = "0.0.0.0";

    open( PACKAGE, "$path" ) || do {
        return $result;
    };

    # Format for the release_version file is
    # 
    # Major:[tab]value
    # Minor1:[tab]value
    # Minor2:[tab]value
    # Release:[tab]value
    #

    foreach $line ( <PACKAGE> )
    {
        #remove the end of line
        #strip white space from the line
        #split the line into key and value using the ":" as the divider

        chomp $line;
        $line =~ s/\s*//g; 
        ( $key, $value ) = split( /:/, $line );        
        $installedVersiondata{ $key } = $value;
    }

    close( PACKAGE );
    $result = $installedVersiondata{ 'Major' } . "." . $installedVersiondata{ 'Minor1' } . "." . $installedVersiondata{ 'Minor2' } . "." . $installedVersiondata{ 'Release' };
    
    
    return $result;
}

###
# args: server path 
sub GetInstalledVersion
{
   my $serverPath      = $_[0];
   my $qtssOutput = "QTSS/0.0.0.0";

    if ( -e $serverPath) {    
        $qtssOutput = `$serverPath -v`;
    }

    ( $InstalledNameAndVersion ) = split( /\s/, $qtssOutput );
    ( $InstalledName, $InstalledVersion ) = split( /\//, $InstalledNameAndVersion );

    return $InstalledVersion;
}

###
# args: path, version number, operator: == > < >= <=
sub ReleaseVersCheck
{ 
    my $newVersion      = $_[0];
    my $operator        = $_[1];
    my $InstalledVersion= $_[2];

    my $debug = 0;

    if (!$operator) {
        $operator = "==";
    }

    @installedVersionArray = split(/\./, $InstalledVersion);
    @newInstallArray = split(/\./, $newVersion);

    if ($debug ) {
        open (FILE, ">/Users/john/Desktop/test.txt");
        print FILE "new=$newVersion old=$InstalledVersion\n";
    }

    my $newVersionComponent;
    my $installedVersionComponent;

    # check the version components i.e. (v1.9.3.1)= v[0].v[1].v[2].v[3]
    for ($i = 0; $i < 4 ; $i++) {
        
        $newVersionComponent = $newInstallArray[$i];
        # force an nth component if it is missing (4.1 -> 4.1.0.0)
        if (!$newVersionComponent) { 
            $newVersionComponent = "0";
        }
    
        $installedVersionComponent = $installedVersionArray[$i];
        # force an nth component if it is missing (4.1 -> 4.1.0.0)
        if (!$installedVersionComponent) {
            $installedVersionComponent = "0"; 
        }

        if ($debug ) {
            print FILE "test i=$i expression = $newVersionComponent $operator $installedVersionComponent\n";
        }

        #stop if a component doesn't match
        if ($installedVersionComponent != $newVersionComponent) {  
            last;
        }
    }

    my $expression = '$newVersionComponent ' . $operator . ' $installedVersionComponent';

    if ($debug ) { 
        print FILE "stop i=$i expression = $newVersionComponent $operator $installedVersionComponent\n";
        if( eval ($expression) )
        {   print FILE "fail ";
        }
        else
        {   print FILE "ok ";
        }
        close (FILE);
    }

    if( eval ($expression) )
    { 
      	#failed
        return 1;
    }
    else
    {
        return 0;
    }
}
