#!perl
# Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "Eclipse Public License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
# 
# Initial Contributors:
# Nokia Corporation - initial contribution.
# 
# Contributors:
# 
# Description:
# 
#

use strict;
use FindBin;
use lib "$FindBin::Bin";
use Getopt::Long;
use File::Path;
use IniData;
use RelData;
use RelTransfer::Export;
use CommandController;


#
# Globals.
#

my $verbose = 0;
my $dummy = 0;
my $force = 0;
my $ftpResume = 0;
my $iniData;
my $commandController;
my $envcomp;
my $envver;
my $examining;
my $excludeSource = 0;
my %failedExports;
my %goodExports;
my %alreadyExported;

#
# Main
#

ProcessCommandLine();
ExportEnvironment();
PrintReport();

#
# Subs.
#

sub ProcessCommandLine {
  Getopt::Long::Configure ("bundling");
  my $help;
  GetOptions("h" => \$help, "v+" => \$verbose, "f" => \$force, "r" => \$ftpResume, "x" => \$examining, "d" => \$dummy, "e" => \$excludeSource);

  if ($help) {
    Usage(0);
  }

  $envcomp = lc($ARGV[0]);
  $envver = $ARGV[1];

  unless (defined $envcomp and defined $envver and $#ARGV = -1) {
    print "Error: Invalid arguments\n";
    Usage(1);
  }
  $iniData = IniData->New(undef,1);
  $commandController = CommandController->New($iniData, 'ExportEnv');
  #if ftp resume option is used override value in reltools.ini
  if ($ftpResume) {
    $iniData->FtpServerSupportsResume(1);
  }
}

sub Usage {
  my $exitCode = shift;

  Utils::PrintDeathMessage($exitCode, "\nUsage: exportenv [options] <component> <external_version>

options:

-h  help
-f  force export overwriting if necessary
-r  use FTP reconnect and resume transfer mode
-x  confirm correct size of files on remote site rather than exporting them
-d  dummy run (don't do anything) - assumes -v
-e  exclude source
-v  verbose output (-vv very verbose)\n");
}

sub ExportEnvironment {
  my $relData = RelData->Open($iniData, $envcomp, $envver, $verbose);
  my $env = $relData->Environment();

  my $exporter = RelTransfer::Export->New(ini_data => $iniData,
					  force => $force,
					  dummy => $dummy,
					  excludeSource => $excludeSource,
					  verbose => $verbose);

  unless ($examining) {
    foreach my $comp (sort keys %{$env}) {
      my $ver = $env->{$comp};
      $exporter->CheckExportable($comp, $ver);
    }
  }

  #do the export checking for errors
  foreach my $comp (sort keys %{$env}) {
    my $exported;
    my $ver = $env->{$comp};
    eval {
      if ($examining) {
        $exporter->ExamineExportedRelease($comp, $ver);
      } else {
        $exported = $exporter->TransferRelease($comp, $ver);
      }
    };
    if ($@) {
      print $@;
      if ($@ =~ /cannot\s+connect/i) {
        print "\nAborting export of $envcomp $envver environment\n";
        last;
      }
      my $error = $@;
      chomp $error;
      $error =~ s/^error: ("?$comp $ver"? )?//i;
      $failedExports{$comp}->{$ver} = $error;
    } else {
      if ($examining || $exported) {
        push @{$goodExports{$comp}}, $ver;
      } else {
        push @{$alreadyExported{$comp}}, $ver;
      }
    }
  }
}

sub PrintReport {
  print "\n=========EXPORT SUMMARY==========\n";

  my $tableData = [["Component", "Version", "status"]];

  foreach my $comp (sort keys %goodExports) {
    foreach my $ver (@{$goodExports{$comp}}) {
      push (@$tableData, [$comp, $ver, 'successfully exported']);
    }
  }
  
  foreach my $comp (sort keys %alreadyExported) {
    foreach my $ver (@{$alreadyExported{$comp}}) {
      push (@$tableData, [$comp, $ver, 'has already been exported']);
    }
  }
  
  if (scalar @{$tableData} > 1) {
    $iniData->TableFormatter->PrintTable($tableData, 1);
  }
  
  #handle failed exports
  if (keys %failedExports) {
    print "\n=========FAILED EXPORTS==========\n";
    print "\nExport Failure Summary\n\n";
    my $failureTableData = [["Component", "Version", "Failure reason"]];
    foreach my $comp (sort keys %failedExports) {
      foreach my $ver (sort keys %{$failedExports{$comp}}) {
        push (@$failureTableData, [$comp, $ver, $failedExports{$comp}->{$ver}]);
      }
    }
    $iniData->TableFormatter->PrintTable($failureTableData, 1);
    print "\nError: Unable to export component release successfully\n";
  }
  else
  {
    if (keys %goodExports) {
      print "\nEnvironment $envcomp $envver successfully exported\n";
    } else {
      print "\nNothing to do!\n";
    }
  }
}

__END__

=head1 NAME

ExportEnv - Exports the environment from which a component release was made.

=head1 SYNOPSIS

  exportenv [options] <component> <version>

options:

  -h  help
  -f  force export overwriting if necessary
  -r  use FTP reconnect and resume transfer mode
  -v  verbose output (-vv very verbose)
  -d  dummy run (don't do anything) - assumes -v
  -e  exclude source
  -x  examine: confirm correct sizes of files on remote site rather than exporting them

=head1 DESCRIPTION

When a release is made, a description of the environment it was made from is stored with it. 
C<ExportEnv> takes a component name and version number, reads the environment data for this 
component and builds a list of component names and version numbers. It then encrypts these releases before sending them to the projects shared archive on a remote site.

Using the C<-f> option will force releases to be exported even if they already exist on the remote site (this only applies to components existing in the users export table)

If the C<-r> option is used and the FTP connection is dropped during the upload of a release, the tools will automatically reconnect to the FTP site and resume the upload. This feature may not be supported by some FTP servers.

Using C<-e> option will create a release without source. 

=head1 KNOWN BUGS

None

=head1 COPYRIGHT

 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
 All rights reserved.
 This component and the accompanying materials are made available
 under the terms of the License "Eclipse Public License v1.0"
 which accompanies this distribution, and is available
 at the URL "http://www.eclipse.org/legal/epl-v10.html".
 
 Initial Contributors:
 Nokia Corporation - initial contribution.
 
 Contributors:
 
 Description:
 

=cut
