########################################################################
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
#
# Module name   : ANDROID.PL
# Module type   : Makefile system
# Compiler(s)   : Perl
# Environment(s): jats
#
# Description:
#       This file provides Toolset initialisation and plugin functions
#       to makelib.pl2
#
# Contents:     Basic (very basic) Android support
#
#............................................................................#

use strict;
use warnings;

#
#   Globals
#
my $androidBuilder;
my $postProcessUnitTest = 0;

##############################################################################
#   ToolsetInit()
#       Runtime initialisation
#
##############################################################################

ToolsetInit();

sub ToolsetInit
{

#.. Toolset configuration
#
    $::ScmToolsetVersion = "1.0.0";                 # our version
    $::ScmToolsetGenerate = 0;                      # generate optional
    $::ScmToolsetProperties{'AutoUnitTests'} = 1;   # Supports AutoUnit Tests

#.. Standard.rul requirements
#
    $::s =   'java';          # Assembler source file
    $::o =   '';              # Object file
    $::a =   'class';         # Library file
    $::so =  'jar';           # Shared library
    $::exe = '.apk';          # Linked binary images

#.. Toolset specific definitions
#
    Init( "android_sdk" );
    ToolsetDefines( 'ANDROID.DEF' );
#
#.. Locate the AndroidBuilder.pl script
#   This will be delivered by a package
#
    my $program = 'AndroidBuilder.pl';
    Verbose("Locate extension Program: $program");
    $androidBuilder = ToolExtensionProgram( $program );
    Error( "Tool program(s) required by toolset not found:", $program)
        unless ($androidBuilder);

    ToolsetDefine ('#   Android Builder Support Tool');
    ToolsetDefine ('ANDROIDBUILDER=' . $androidBuilder);

}

########################################################################
#
#   Generate a project from the provided build.xml
#
#   Arguments   : $name             - Base name of the project
#                 $androidxml       - Path to the AndroidManifest.xml file
#                 $pArgs            - Project specific options
#                 $auto_test        - Unit Test Target (optional)
#                 $unit_test        - Unit Test Target (optional)
#                 $pGenerated       - Ref to an array of Generated Files (optional)
#
########################################################################

our $ToolsetPROJECT_type = 'android';
sub ToolsetPROJECT
{
    my( $name, $androidxml ,$pArgs, $auto_test, $unit_test, $pGenerated ) = @_;

    #
    #   Populate the project for the user
    #
    ToolsetPROJECTPreBuild (@_);

    #
    #   Generate the recipe to create the project
    #   Add names of co-generated targets.
    #
    my $me = MakeEntry::New (*MAKEFILE, 'Project_'.$name );
    $me->AddComment ("Build Android Project: $name" );
    $me->AddDependancy ( $androidxml );
    $me->AddDependancy ( '$(SCM_MAKEFILE)' );
    $me->AddDependancy ( @{$pGenerated} );
    $me->AddRecipe ( "\$(XX_PRE)\$(call ProjectDefine_$name,)"  );
    $me->Print();

    #
    #   Generate the recipe to clean the project
    #
    $me = MakeEntry::New (*MAKEFILE, 'ProjectClean_'.$name );
    $me->AddComment ("Clean Android Project: $name" );
    $me->AddRecipe ( "\$(XX_PRE)\$(call ProjectDefine_$name,-clean)"  );
    $me->Print();

    #
    #   Generate the recipe to run unit tests on the project
    #   This is optional
    #
    if ( $auto_test )
    {
        $me = MakeEntry::New (*MAKEFILE, 'ProjectATest_'.$name );
        $me->AddComment ("Auto Test project: $name" );
        $me->AddDependancy ( $androidxml );
        $me->AddRecipe ( "\$(XX_PRE)\$(call ProjectDefine_$name,'-autotest')"  );
        $me->Print();

        #   Flag that we need to post process the test results
        #   Under Java the UTF tests MUST be Post processed
        $postProcessUnitTest = 1;

    }

    if ( $unit_test )
    {
        $me = MakeEntry::New (*MAKEFILE, 'ProjectUTest_'.$name );
        $me->AddComment ("Unit Test project: $name" );
        $me->AddDependancy ( $androidxml );
        $me->AddRecipe ( "\$(XX_PRE)\$(call ProjectDefine_$name,$unit_test)"  );
        $me->Print();
    }

    #
    #   Generate macro to contain the project invocation
    #   The first argument will be a 'build target' argument
    #
    my @cmdargs;
    push @cmdargs, '$(GBE_PERL)','$(ANDROIDBUILDER)';
    push @cmdargs, '-f', $androidxml;
    push @cmdargs, '-i=$(PWD)/$(INTERFACEDIR)';
    push @cmdargs, '-t=$(GBE_TYPE)';
    push @cmdargs, '-pf=$(GBE_PLATFORM)';
    push @cmdargs, '-pn=$(GBE_PBASE)', '-pv=$(BUILDVER)';
    push @cmdargs, '-hasTests' if ( $auto_test || $unit_test );
    push @cmdargs, '$(VERBOSE_OPT)';
    push @cmdargs, @{$pArgs}, '$1';

    $me = MakeEntry::New (*MAKEFILE, 'ProjectDefine_'.$name, '--Define' );
    $me->AddComment ("Macro to invoke project: $name" );
    $me->AddRecipe ( join(' ', @cmdargs)  );
    $me->Print();
}

#-------------------------------------------------------------------------------
# Function        : ToolsetPROJECTPreBuild 
#
# Description     : This ANDROID Specific operation is used to perform some of the 
#                   build opertaions at 'build' time. These include:
#                       - Verify that required packages are available
#                       - Populate the targets 'libs' directory so that the user can
#                         develop with the external dependencies in place 
#
# Inputs          : $name             - Base name of the project
#                   $androidxml       - Path to the AndroidManifest.xml file
#                   $pArgs            - Project specific options
#                   $auto_test        - Unit Test Target (optional)
#                   $unit_test        - Unit Test Target (optional)
#                   $pGenerated       - Ref to an array of Generated Files (optional)
#
# Returns         : Nothing
#
sub ToolsetPROJECTPreBuild
{
    my( $name, $androidxml ,$pArgs, $auto_test, $unit_test, $pGenerated, $project ) = @_;

    #
    #   Determine the populate mode
    #   Used to limit the shared libraries that are included
    #   In populate mode may have both -tD and -tP
    #       Need -tD last for backward compatability
    #
    my @tArgs;
    if (exists $project->{Prod} && $project->{Prod}) {
        push @tArgs, '-t=P';
    } elsif (exists $project->{Debug} && $project->{Debug}) {
        push @tArgs, '-t=D';
    } else {
        push @tArgs, '-t=P', '-t=D';
    }

    #
    #   Invoke the androidBuilder in a mode so that it will populate the Eclipse project
    #   in a suitable manner.
    #
    EnvImport( "GBE_PERL" );
    System ( '--NoShell', '--Exit', $::GBE_PERL, $androidBuilder, 
             '-f', $androidxml,
             '-i', catdir( $::ScmRoot, $::ScmInterface),
             @tArgs,
             '-pf', $::ScmPlatform,
             '-pn', $::Pbase,
             '-pv', $::ScmBuildVersionFull,
             '-populate',
             @{$pArgs}
           );
}

#-------------------------------------------------------------------------------
# Function        : ToolsetPostprocess 
#
# Description     : Last chance by the toolset to perform processing
#                   All Directives have been processed
#
#                   If the Project has indicated that it has an automated unit test
#                   then we need to post process the results
#
# Inputs          : None
#
# Returns         : 
#

sub ToolsetPostprocess
{
    if ($postProcessUnitTest)
    {
        MakeHeader ("Automated tests Post Processing");

        #   Extend the list of Post Unit Tests recipes that are run
        my $recipeName = 'post_utf_processing';
        ToolsetAddUnitTestPostProcess($recipeName);

        #
        #   Create the Post Unit Test Recipe
        #
        my $me = MakeEntry::New (*MAKEFILE, $recipeName, '--Phony' );

        #   Insert test EnvVars
        #       In the Java toolset these are not as useful in a Jats RunTest
        $me->AddDefn('export GBE_UTFNAME', 'AndroidStudioTest');
        $me->AddDefn('export GBE_UTFUID', '$(MAKEFILEUID)' . '_' . '1');
        $me->AddDefn('export GBE_UTFFILE','$(UTFDIR_PKG)/$(GBE_PLATFORM)-$(GBE_TYPE)-$(GBE_UTFUID)' . '.xml');
        $me->AddDefn('export GBE_UTFTEST','TEST-$(GBE_UTFNAME)-$(GBE_TYPE)-$(GBE_UTFUID)' );

        $me->SectionIfDef ('UTF_POSTPROCESS');
        $me->AddRecipe  ( [
                           '$(GBE_PERL) -Mjats_runutf -e processUtf -- ',
                           '$(VERBOSE_OPT)',
                           '-filter=androidStudio',
                           '-root=$(GBE_ROOT_ABS)',
                           '-target=$(GBE_PLATFORM)', 
                           '-pkgdir=$(PKGDIR)',
                           '-local=$(LOCALDIR)',
                           '-interface=$(INTERFACEDIR)' 
                          ]);
        $me->Print();

        #   Clean up files that look like Junit output files
        ToolsetGenerate( 'TEST-*.xml' );
    }
}


1;

