########################################################################
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
#
# Module name   : jats.sh
# Module type   : Jats utility program
# Environment(s): jats
#
# Description   : Create auto.pl for package against specified release
#                 Needs rtag_id and access to the Release Manager database
#
# Usage:
#
#......................................................................#

require 5.006_001;
use strict;
use warnings;

use JatsError;
use JatsVersionUtils;
use JatsRmApi;
use JatsSystem;

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

my $RM_DB;

################################################################################
#   Global data
#
my $VERSION = "1.0.0";
my %ReleasePackages;            # Packages in the release
my %BuildPackages;              # Packages for this build
my $ReleaseName;
my $ProjectName;

#
#   Options
#
my $opt_help = 0;
my $opt_verbose = 0;
my $opt_rtagid;

my $result = GetOptions (
                "help|h:+"          => \$opt_help,
                "manual:3"          => \$opt_help,
                "verbose:+"         => \$opt_verbose,       # flag or number
                "rtagid|rtag_id=s"  => \$opt_rtagid,
                );

#
#   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_help > 2);

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


Error( "Need rtagid" )
    unless ( $opt_rtagid );

#
#   Connect to the RM database
#       Uses infor from the JATS environment
#           GBE_RM_LOCATION
#           GBE_RM_USERNAME
#           GBE_RM_PASSWORD
#
connectRM(\$RM_DB);

#
#   Ensure that the RTAG exists
#   Extract the Release and Project Name
#
GetReleaseData( $opt_rtagid );
Error ("Rtag not found in Release Manager Database: $opt_rtagid") unless ( $ProjectName );
Message ("Project Name: $ProjectName");
Message ("Release Name: $ReleaseName");
#
#   Get all package info the specified release
#   This is done as one query so it should be fast
#
getPkgDetailsByRTAG_ID( $opt_rtagid );

#
#   Create a configuration file for use by the JATS rewrite tool
#   This will allow the build.pl file to be re-written
#
my $file = "jats_rewrite.cfg";
open CFG, ">$file" || Error("Cannot create $file", $! );
print CFG "releasemanager.projectname = $ProjectName\n";
print CFG "releasemanager.releasename = $ReleaseName\n";

foreach my $pkg ( sort keys %ReleasePackages )
{
    my $ver;
    foreach my $prj ( sort keys %{$ReleasePackages{$pkg}} )
    {
        $ver  = $ReleasePackages{$pkg}{$prj};
        $ver .= '.' . ${prj} if ( $prj );
        print CFG "${pkg} ${ver}\n";
    }
}
close CFG;

#
#   Massage the build.pl file to create the auto.pl file
#   That will be used to create the final package.
#
JatsTool ("jats_rewrite.pl", "-conf", $file, "-verb=$opt_verbose", "-mode=1" ) && Error("Did not rewrite build.pl file");

exit 0;

#-------------------------------------------------------------------------------
# Function        : GetReleaseData
#
# Description     : Determine the Release Name and associated project
#
# Inputs          : $rtag_id
#
# Returns         : 
#
sub  GetReleaseData
{
    my ($RTAG_ID) = @_;
    my $foundDetails = 0;
    my (@row);

    # First get details from pv_id

    my $m_sqlstr = "SELECT rt.RTAG_NAME, p.PROJ_NAME" .
                    " FROM release_manager.RELEASE_TAGS rt, release_manager.PROJECTS p" .
                    " WHERE rt.RTAG_ID = $RTAG_ID AND rt.PROJ_ID = p.PROJ_ID ";

    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( @row = $sth->fetchrow_array )
                {
#                    print "@row\n";
                    ($ReleaseName, $ProjectName) = @row;
                    last;
                }
            }
            $sth->finish();
        }
        else
        {
        Error("Execute failure: GetReleaseData" );
        }
    }
    else
    {
        Error("Prepare failure: GetReleaseData" );
    }
}

#-------------------------------------------------------------------------------
# Function        : getPkgDetailsByRTAG_ID
#
# Description     : 
#
# Inputs          : rtag_id
#
# Returns         : Populate %ReleasePackages
#
sub getPkgDetailsByRTAG_ID
{
    my ($RTAG_ID) = @_;

    # First get details from pv_id

    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
                    " FROM RELEASE_MANAGER.RELEASE_CONTENT rc, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
                    " WHERE rc.RTAG_ID = $RTAG_ID AND rc.PV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
    my $sth = $RM_DB->prepare($m_sqlstr);
    if ( defined($sth) )
    {
        if ( $sth->execute( ) )
        {
            if ( $sth->rows )
            {
                while ( my @row = $sth->fetchrow_array )
                {
                    my $pv_id   = $row[0];
                    my $name    = $row[1];
                    my $ver     = $row[2];
#                    print "$name $ver\n";

                    #
                    #   Store data package name and package suffix
                    #
                    my ( $pn, $pv, $pp ) = SplitPackage( $name, $ver );
                    $ReleasePackages{$pn}{$pp} = $pv;
                }
            }
            $sth->finish();
        }
    }
    else
    {
        Error("Prepare failure" );
    }
}

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

=pod

=head1 NAME

jats_rewrite - Rewrite a build.pl file

=head1 SYNOPSIS

  jats etool jats_rewrite [options]

 Options:
    -help               - brief help message
    -help -help         - Detailed help message
    -man                - Full documentation
    -verbose            - Verbose operation
    -rtagid=nnn         - Release Tag

=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>

Increases program output. This option may be specified multiple times

=item B<-rtagid=nnn>

This option specifies the Release, within the Release Manager Database, that will
be used to update the build dependency file.

The Release Tag is provided by the Release Manager Web Page.

This option is mandatory.

=back

=head1 DESCRIPTION

This utilty will update the dependency information within a build file to
reflect the desired package-versions within a specified release.

The intent of this utility is to simplify the process of package development by
automating the creating of a packages dependencies.

The utility will:

=over 8

=item * Contact the Release Manager Database.

The credentials are provided via JATS environment variables. JATS msut be
correctly configured in order for this to work.

=item * Locate the release as specified by the Release Tag

The name of the Release and the containing Project will be displayed.

=item * Extact all package-versions within the release

The information is then written to a file called jats_rewrite.cfg. The file is
left in place by the utility. It may be deleted.

=item * Invoke the jats rewrite utility to create or modify the build files.

Only the package dependencies are modified. The package version itself is not modified.

=back

The resultant file will be called 'auto.pl'. Jats will use this file in preference
to the build.pl file.

The original 'build.pl' file is used as a template for updating version
numbers. The tool will not add or remove packages from the build file.

If an 'auto.pl' file has already been created, then this utility will re-use it.
This allows a developer to modify the file without fear of losing the changes.

=cut

