#! /usr/bin/perl
########################################################################
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
#
# Module name   : jats_deploy.pl
# Module type   : Makefile system
# Compiler(s)   : n/a
# Environment(s):
#
# Description   : This script is run via the JATS wrapper script
#                 The script will setup an environment suitable for the
#                 processing of the deployfile.pl script
#
#                 NOTE:
#                 Appears to be the start of something.
#                   Don't know where Deploy.cfg is generated or what it
#                   might contain.
#
#                   Dosn't actually call the deployfile. Perhaps that was the
#                   next step.
#
#......................................................................#

require 5.006_001;
use strict;
use warnings;
use JatsError;

use Data::Dumper;                           # Debug only
use Pod::Usage;                             # required for help support
use Getopt::Long;
use Cwd;

my $VERSION = "1.0.0";                      # Update this

#
#   Options
#
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
my $opt_help = 0;
my $opt_manual = 0;

#
#   Globals
#
my $GBE_PERL     = $ENV{'GBE_PERL'};        # Essential ENV variables
my $GBE_CORE     = $ENV{'GBE_CORE'};
my $USER         = $ENV{'USER'};
my $GBE_MACHTYPE = $ENV{'GBE_MACHTYPE'};

#
#   Imported Globals (configuration)
#
our @deploy_cf_args;
our $ScmBuildName;
our $ScmBuildPackage;
our $ScmBuildVersion;
our $ScmBuildVersionFull;
our $ScmBuildProject;
our $ScmBuildPreviousVersion;
our $ScmSrcDir;
our @BUILDPLATFORMS;
our %ScmBuildAliases;
our @DEFBUILDPLATFORMS;
our %ScmBuildPlatforms;
our %BUILDPLATFORM_PARTS;

#
#   Working variables
#
my $deployfile;

#-------------------------------------------------------------------------------
# Function        : Mainline Entry Point
#
# Description     :
#
# Inputs          :
#
my $result = GetOptions (
                "help+"         => \$opt_help,              # flag, multiple use allowed
                "manual"        => \$opt_manual,            # flag, multiple use allowed
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
                );

                #
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
                #

#
#   Process help and manual options
#
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
pod2usage(-verbose => 1)  if ($opt_help == 2 );
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));

#
#   Configure the error reporting process now that we have the user options
#
ErrorConfig( 'name'    =>'DEPLOY',
             'verbose' => $opt_verbose,
             'debug'   => $opt_debug
             );

#
#   Validate user options
#

#
#   Locate the JATS generated data file
#   This will be in the "interface" directory, or if this directory does not
#   exist the file will be found in the current directory. The name of the
#   interface directory is not well defined. It may be called interface
#   but it may not. It will be one directory below the build directory.
#
#   The data file can be "require"ed directly by Perl.
#
my $idir;
opendir (DIR, "." ) or Error( "Cannot open the current directory");
while ( $_ = readdir( DIR ) )
{
    next if ( $_ =~ m/\./ );
    next unless ( -d $_ );
    if ( -f "$_/Build.cfg" )
    {
        Verbose ("Search for Build.cfg in: $_");
        Warning( "Multiple interface directories located" )
            if ( $idir );
        $idir = $_;
    }
}
closedir DIR;
Error ("No suitable interface directory located") unless defined($idir);

#
#   Read in the general Build.cfg data and the Deploy.cfg data
#
#for (qw(Build.cfg Deploy.cfg))
for (qw( Build.cfg ))
{
    my $fname = $_;
    $fname = "$idir/$_" unless ( -f $_ );
    Verbose ("Check for: $fname");
    Error( "Cannot locate $fname") unless ( -f $fname );
    require $fname;
}

#
#   Display useful information
#
if ( $opt_verbose )
{
    print "Build Parameters\n";
    print "     ScmBuildName             $::ScmBuildName\n";
    print "     ScmBuildPackage          $::ScmBuildPackage\n";
    print "     ScmBuildVersion          $::ScmBuildVersion\n";
    print "     ScmBuildProject          $::ScmBuildProject\n";
    print "     ScmBuildVersionFull      $::ScmBuildVersionFull\n";
    print "     ScmBuildPreviousVersion  $::ScmBuildPreviousVersion\n";
    print "     ScmSrcDir                $::ScmSrcDir\n";
    

    print "\nBuildDeploy Arguments\n";
    foreach (@::deploy_cf_args )
    {
        print "     $_\n";
    }
}

#
#   Locate the deployfile.pl
#   This MUST be in the directory specified ScmSrcDir or the build directory
#
foreach ( ".", $::ScmSrcDir )
{
    next unless( -f "$_/deployfile.pl" );
    Warning("Multiple deployfile.pl file found") if ( $deployfile );
    $deployfile = "$_/deployfile.pl";
}

Error("deployfile.pl not found")
    unless ( $deployfile );
Verbose("Deployment script: $deployfile" );

#
#   Invoke the deployfile.pl for each required platform
#   The platforms have been specified by the user on the command line
#
#   There are some special processing rules (largely to look like make )
#
#       all         - process all default platforms
#       XXXX        - process production and debug for XXXX
#       XXXX_debug  - process debug for XXXX
#       XXXX_prod   - process production for XXXX
#
if ( $#ARGV < 0  )
{
    #
    #   Display a list of available comamnd targets
    #
    print "Available platforms include:\n";
    print "     all, debug, prod\n";
    print "     " . join ( ', ', @::DEFBUILDPLATFORMS) . "\n";

    print "\n";
    Warning("Nothing to do" );
}

foreach my $platform ( @ARGV )
{
    my $gdebug = 1;
    my $gprod = 1;
    my @platform_list;

    #
    #   Extract _prod and _debug information
    #
    $gprod = 0  if ( $platform =~ m/_debug$/ );
    $gdebug = 0 if ( $platform =~ m/_prod$/ );
    $platform =~ s/_debug$|_prod$//;

    #
    #   Create a list of platforms to process
    #
    if ( $platform eq 'all' ) {
        @platform_list = @::DEFBUILDPLATFORMS;
        Verbose ("Alias of all: @platform_list");

    } elsif ( defined $::ScmBuildAliases{$platform} ) {
        #
        #   Remove options from the Alias list to leave platforms
        #
        @platform_list = grep{!/^--/} split( ' ', $::ScmBuildAliases{$platform});
        Verbose ("Alias of $platform: @platform_list");

    } else {
        my $found;
        foreach  ( @::BUILDPLATFORMS )
        {
            if ( $_ eq $platform )
            {
                $found++;
                last;
            }
        }
        Error( "Platform not known: $platform")
            unless ( $found );

        push @platform_list, $platform;
    }

    #
    #   Process each platform in the list
    #   These may need to be done for both the debug and production flavor
    #   Examine the platform arguments to pickup build specified limits
    #
    foreach my $platform ( @platform_list )
    {
        #
        #   Process platform arguments looking for OnlyProd and OnlyDebug
        #   This will then modify the global user request
        #
        my $debug = $gdebug;
        my $prod = $gprod;

        my @platform_ops = split( "$;", $::ScmBuildPlatforms{$platform} );
        foreach  ( @platform_ops )
        {
            $prod = 0 if ( m/^--OnlyDebug/ );
            $debug = 0 if ( m/^--OnlyProd/ )
        }
        Verbose( "Platform: $platform, debug:$debug, Prod:$prod");
        process_platform( $platform, "D" ) if ( $debug );
        process_platform( $platform, "P" ) if ( $prod );
        Warning ("Nothing to do for: $platform") unless ( $debug || $prod );
    }
}

#-------------------------------------------------------------------------------
# Function        : process_platform
#
# Description     : Perform processing for one platform
#
# Inputs          : $platform       - platform to process
#                   $type           - P or D
#
# Returns         : Nothing
#
sub process_platform
{
    my( $platform, $type ) = @_;
    my @parts = @{$BUILDPLATFORM_PARTS{$platform}};

    my $target = $parts[-1];            # Last one is the target
    my $product = $parts[1];            # 2nd one is the product

    print "---- Processing $platform ($product, $target), $type\n";
    

    system ( $GBE_PERL,
            '-w',  $deployfile,                 # File to process
		    '-r', '.' ,                         # Root directory
		    '-n', $::ScmBuildName,              # Package Name
		    '-d', lc($::ScmBuildName),          # Directory
		    '-v', $::ScmBuildVersionFull,       # Build version
		    '-t', $type,                        # Build type
		    '-o', $::ScmBuildPreviousVersion,   # Previous Version
		    '-m', $platform,                    # Platform
		    '-g', $target,                      # Target
		    '-k', $product );                   # Product

}

#-------------------------------------------------------------------------------
#   Documentation
#

=pod

=head1 NAME

jats_deploy - Process deployfile.pl's

=head1 SYNOPSIS

  jats deploy [options] action

 Options:
    -help              - brief help message
    -help -help        - Detailed help message
    -man               - Full documentation
    -verbose           - Generate verbose output

 Actions:
    all                 - Debug and Production builds
    debug               - Debug build of all platform
    prod                - Production build of all platforms
    other*              - Specify a single platform. Optional _prod or _debug

=head1 OPTIONS

=over 8

=item B<-help>

Print a brief help message and exits.

=item B<-help -help>

Print a detailed help message with an explanation for each option.

=item B<-man>

Prints the manual page and exits.

=item B<-verbose>

Incresed the level of output generated by the program.

=back

=head1 DESCRIPTION

This program is the primary tool for the invocation of the deployfile.pl scripts

In normal operation the program will:

=over 8

=item Setup the environment

Read the deploy.cfg file from the interface directory.

=item Locate and execute the deployfile.pl

This file MUST be located in the primary source directory. The same directory
as the top level makefile.

=back

=cut

