#! /usr/bin/perl


my ($prefix, $globus_prefix, $exec_prefix, $bindir, $sbindir, $libdir);
my ($datarootdir, $datadir, $perlmoduledir, $gptdatadir);
my ($gptexecsharedir, $amdir, $pkg_confdir, $aclocaldir);

if (exists $ENV{GPT_LOCATION})
{
    $prefix = $ENV{GPT_LOCATION};
}
else
{
    $prefix = "/usr";
}

if (exists $ENV{GLOBUS_LOCATION})
{
    $globus_prefix = $ENV{GLOBUS_LOCATION};
}
else
{
    $globus_prefix = "/usr";
}

$exec_prefix = "${prefix}";
$bindir = "${exec_prefix}/bin";
$sbindir = "${exec_prefix}/sbin";
$libdir = "${exec_prefix}/lib";
$datarootdir = "${prefix}/share";
$datadir = "${prefix}/share";
$perlmoduledir = "/usr/share/perl5";
$gptdatadir = "${datadir}/globus/gpt";
$gptexecsharedir = "${datadir}/globus/gpt";
$amdir = "${datadir}/globus/amdir";
$pkg_confdir = "${datadir}/globus/gpt";
$aclocaldir = "${datadir}/globus/aclocal";

unshift(@INC, "${perlmoduledir}");

use Data::Dumper;

use strict;
use Carp;
use Getopt::Long;
use Config;

#
# Do a perl check for version >= 5.005.
#

if ( ! ( defined eval "require 5.005" ) )
{
    die "GPT requires at least Perl version 5.005";
}

my $verbose;

if ( ! -d "$datadir/globus/packages" )
{
    die("Can't find a globus/packages directory to work on in your GLOBUS_LOCATION!\n");
}

system("$sbindir/gpt_version") == 0
         or die "GPT died due to Version mismatch.  Check PATH and GPT_LOCATION\n" ;


if ( ! ( defined eval "require Grid::GPT::GPTObject" ) )
{
    die("$prefix does not appear to hold a valid GPT installation\n");
}

require Pod::Usage;

#
# argument specification
#

my ($sdk, $help, $man, $version, $bundle, $globusdir, $bundle_style);

GetOptions(
           'sdk'          => \$sdk,
           'help|?'       => \$help,
           'man'          => \$man,
           'version'      => \$version,
           'bundles|b'       => \$bundle,
           'location=s'   => \$globusdir
          )
  or Pod::Usage::pod2usage(0);

Pod::Usage::pod2usage(1) if $help;
Pod::Usage::pod2usage(-verbose => 2) if $man;

require Grid::GPT::GPTIdentity;
Grid::GPT::GPTIdentity::print_gpt_version() if defined $version;

require Grid::GPT::Installation;
require Grid::GPT::BundleInstallation;
require Grid::GPT::SetupInstallation;
require Grid::GPT::PkgSet;

my $locations = new Grid::GPT::Locations(
                                         installdir => $globusdir,
                                        );



main($sdk);

### main( )
#
# check the user's GLOBUS_LOCATION for a cohoerent grid system
#

sub main
{
    my ($sdk) = @_;


    my $installation = new Grid::GPT::Installation(
                                                   locations => $locations,
                                                  );

    check_bundles( inst => $installation );

    my ($depnode, $failed, $rc, $msg);

    $failed = 0;
    $installation->cleardepenv();

    if ($sdk)
    {
        printf("Verifying development dependencies...\n");
        $installation->set_depenv('Build');
        $rc = $installation->check_missing(die => 0, log => \$msg);
        $installation->cleardepenv();
        $failed += $rc;
        print $msg if $rc;
    }
    else
    {
        printf("Verifying run-time dependencies...\n");
        $installation->set_depenv('Runtime');
        $rc = $installation->check_missing(die => 0, log => \$msg);
        $installation->cleardepenv();
        $failed += $rc;
        print $msg if $rc;

        printf("\nVerifying setup dependencies...\n");
        $installation->set_depenv('Setup');
        $rc = $installation->check_missing(die => 0, log => \$msg);
        $installation->cleardepenv();
        $failed += $rc;
        print $msg if $rc;

        printf("\nVerifying setup packages...\n");
        $rc = check_missing_setup($installation);
        $failed += $rc;
    }

    #
    # check_missing() will return true if any packages are missing
    #

    printf("\n");
    if ($failed > 0)
    {
        printf("ERROR: The collection of packages in $prefix is not coherent!\n");
    }
    else
    {
        printf("The collection of packages in $prefix appear to be coherent.\n");
    }

    return;
}

sub check_missing_setup
{
    my $installation = shift;

    my $setupinstallation = 
      new Grid::GPT::SetupInstallation(
                                       locations => $locations,
                                      );
    my $list = $installation->setup_pkgs();

    $list = $setupinstallation->check_for_setup_needs(pkgs => $list);
    @$list = grep {$_->pkgtype() =~ m!pgm! } @$list;

    if (scalar(@$list) > 0)
    {
        printf("The following setup packages still need to be configured via gpt-postinstall:\n");
        for my $l (@$list)
        {
            printf("\t%s\n", $l->label());
        }

        return 1;
    }
    else
    {
        return 0;
    }
}

sub check_bundles
{
  my %args         = @_;

  my $installation = $args{'inst'};

  my $bndlinst     = 
    new Grid::GPT::BundleInstallation(
                                          locations => $locations,
                                         );

  print "Verifying Bundles...\n";
  $bndlinst->check_all_bundles_integrity( installation => $installation );

  exit if( defined( $bundle ) );
}

=head1 NAME

B<gpt-verify> - Verify dependencies needed for Globus are avaliable. 

=head1 SYNOPSIS

gpt-verify [ -sdk -bundle -help -version -man ]

=head1 DESCRIPTION

B<gpt-verify> is used to verify both runtime and setup dependencies along
with setup packages for the current Globus installation.  B<gpt-verify> will
serach through the list of dependencies and make sure that each is met.  If
a problem is found, B<gpt-verify> will exit with an error and list missing
files. 

=head1 OPTIONS

=over 4

=item B<-sdk>: Verify build dependencies.

=item B<-bundle>

Verify installed bundles only.

=item B<-help>

Print a brief help message and exits.

=item B<-man>

Prints the manual page and exits.

=item B<-version>

Prints the version of GPT and exits.

=back

=head1 SEE ALSO

gpt-install(8) gpt-uninstall(8) gpt-query(8) gpt-postinstall(8)

=head1 AUTHOR

Michael Bletzinger E<lt>mbletzin.ncsa.uiuc.eduE<gt> and Eric Blau
E<lt>eblau.ncsa.uiuc.eduE<gt>

=cut
