# Copyright 1999-2012. Parallels IP Holdings GmbH. All Rights Reserved.
package ArchiveContent::UnixArchiveContent;

use strict;
eval{require warnings;1;};

use Logging;
use AgentConfig;
use ArchiveContent::ArchiveContent;

use vars qw|@ISA|;

@ISA = qw|ArchiveContent::ArchiveContent|;

sub new {
  my $self = {};
  bless( $self, shift );
  $self->_init(@_);
  return $self;
}

sub _init {
  my ( $self, $storage, $packer ) = @_;
  $self->{storage} = $storage;
  $self->{packer} = $packer;
  Logging::debug("Unix Archive content transport has been initialized");
}


sub addRemoteTar {
    my ($self, $proposedId, %options) = @_;
    
    my $fileName = $self->_prepareDataForRemoteBackupAgent ($proposedId, \%options);
    
    my $response = undef;
    
    $response = $self->_callRemoteCommand('backup-content', $fileName, \%options);
    
    $response = $self->_callRemoteCommand('get-logs', $fileName, \%options);
    Logging::debug("Logs from remote node:" . $response);
    
    # In this variable information from remote host about created archives are stored
    my $storage1 = undef;
    $response = $self->_callRemoteCommand('get-created-content-info', $fileName, \%options);
    eval($response);
    
    $response = $self->_callRemoteCommand('destroy-session', $fileName, \%options);
    
    unlink $fileName;
    
    return $storage1;
}

sub _prepareDataForRemoteBackupAgent {
    my ($self, $proposedId, $options) = @_;

    my $tmpFileContent = '';
    # create file with input parameters for $storage->addTar method on remote host
    $tmpFileContent = "%options = (";
    foreach my $key (keys %$options) {
      if (ref($options->{$key}) eq 'ARRAY') {
        $tmpFileContent .= "'$key'" . "=>" . "['" . join("','", @{$options->{$key}}). "'] , ";
      } else {
        $tmpFileContent .= "'$key'" . "=>" . "'$options->{$key}'" . ',';
      }
    }
    $tmpFileContent .= ");";
    
    $tmpFileContent .= "\$proposedId = '". $proposedId ."';";

    # save also information for storage initialization
    $tmpFileContent .= "\$passwd = '". $self->{storage}->{ftpsettings}->{password}."';";
    $tmpFileContent .= "\$do_gzip = '". $self->{storage}->{gzip_bundle}."';";
    $tmpFileContent .= "\$workDir = '". $self->{storage}->{output_dir}."';";
    $tmpFileContent .= "\$splitSize = '". $self->{storage}->{split_size}."';";
    $tmpFileContent .= "\$space_reserved = '". $self->{storage}->{space_reserved}."';";
    $tmpFileContent .= "\$passiveMode = '". $self->{storage}->{passive_mode}."';";
   
    # session identificator on remote node
    $tmpFileContent .= "\$sessionId = '".HelpFuncs::mktemp("XXXXXXXX")."';";

    my $fileName = $self->_writeContentToTempFile($tmpFileContent);
    
    return $fileName;
}


### Private routines ###

sub _addTar {
  my $self = shift;
  my $cid_type = shift;
  my $dstFile = shift;  
  return undef if exists $self->{packer}->{skip_content};
  
  my %options = @_;
  
  if (defined $options{'remoteip'}) {
    my $remoteStorage = $self->addRemoteTar( $dstFile, %options);
    return undef unless defined $remoteStorage;
    return $self->_makeCidNodeFromRemote($dstFile, $cid_type, $remoteStorage);
  } else {
    my $id = $self->{storage}->addTar( $dstFile, @_);
    return undef unless defined $id;
    return $self->_makeCidNode( $id, $cid_type );
  }
}


sub _makeCidNode{
  my ($self, $id, $cid_type ) = @_;
  my $cid = XmlNode->new( 'cid' );
  $cid->setAttribute( 'type', $cid_type );
  $cid->setAttribute( 'unpacksize', $self->{storage}->getFilesUnpackSizeFromId($id) );
  $cid->setAttribute( 'path', $self->{storage}->getFilePathFromId( $id ) );
  my $files = $self->{storage}->getFilesFromId( $id );
  foreach my $filedata( @{$files} ){
    $cid->addChild( XmlNode->new( 'content-file', 'content' => $filedata->[0], 'attributes' => {'size' => $filedata->[1] } ) );
  }
  return $cid;
}

sub _makeCidNodeFromRemote{  
  my ($self, $proposedId, $cid_type, $storage) = @_;
  my ($destDir, $destFile, $id) = $storage->getFileNameIdFromId( $proposedId, $storage->getDefExtension(), 1 );
  my $cid = XmlNode->new( 'cid' );
  $cid->setAttribute( 'type', $cid_type );
  $cid->setAttribute( 'unpacksize', $storage->getFilesUnpackSizeFromId($id) );
  $cid->setAttribute( 'path', $storage->getFilePathFromId( $id ) );
  my $files = $storage->getFilesFromId( $id );
  foreach my $filedata( @{$files} ){
    $cid->addChild( XmlNode->new( 'content-file', 'content' => $filedata->[0], 'attributes' => {'size' => $filedata->[1] } ) );
  }
  return $cid;
}

sub _addDb {
  my $self = shift;
  my $cid_type = shift;
  my $dstFile = shift;
  return if exists $self->{packer}->{skip_content};
  my $id = $self->{storage}->addDb( $dstFile, @_);
  if ( defined $id ) {
    return $self->_makeCidNode( $id, $cid_type);
  }
  return;
}

1;