# Copyright 1999-2016. Parallels IP Holdings GmbH. All Rights Reserved.
package Storage::ArchiveStorage;

use strict;
use warnings;

use File::Basename qw(basename);
use IPC::Run;
use HelpFuncs;
use Logging;
use Storage::Storage;

use vars qw|@ISA|;
@ISA = qw|Storage::Storage|;

sub _init {
  my ($self, %options) = @_;

  $self->SUPER::_init(%options);
  $self->{exportDir} = $options{'export-dir'};
  $self->{ftp} = $options{'ftp'};
  $self->{sessionPath} = $options{'session-path'};
  $self->{verbose} = $options{'verbose'};
  $self->{cmd} = undef;
  $self->{cmdInput} = '';
  $self->{cmdOutput} = '';

  Logging::debug("-" x 60);
  Logging::debug("ARCHIVE storage initialized.");
  Logging::debug("Base directory: $self->{output_dir}");
  Logging::debug("Space reserved: $self->{space_reserved}");
  Logging::debug("Gzip bundles: " . ($self->{gzip_bundle} ? "yes" : "no"));
  Logging::debug("Bundle split size: " . ($self->{split_size} || "do not split"));
  Logging::debug("-" x 60);
  $self->reserveSpace();
}

sub finishExport {
  my $self = shift;

  my $mainDumpFile = $self->getMainDumpXmlRelativePath();
  if ($mainDumpFile) {
    my $mainDumpFileName = basename($mainDumpFile);
    eval {
      Logging::debug("Add file $mainDumpFileName to archive");
      $self->{cmdInput} .= "$mainDumpFileName\n";
      IPC::Run::pump($self->_getCmd());
    };
    if ($@) {
      Logging::warning(sprintf('Unable to upload dump file %s to FTP storage: %s', $mainDumpFileName, $@));
    }
  }
  $self->_finishCmd();
}

sub createRepositoryIndex{
  my ($self, $index) = @_;
}

sub writeDiscovered{
  my $self = shift;

  $self->_writeDiscovered(@_);
}

sub moveFileToDiscovered {
  my $self = shift;

  $self->_moveFileToDiscovered(@_);
}

sub addTar {
  my $self = shift;

  my ($ret, $destDir, $files) = @{$self->_addTar(@_)};
  return $ret unless $ret;

  my $file;
  eval {
    my $dumpStorage = $self->{mainDumpRootPath} ? sprintf('%s/%s', $self->{output_dir}, $self->{mainDumpRootPath}) : $self->{output_dir};
    my $destDirRelativePath = substr($destDir, length($dumpStorage));
    $destDirRelativePath =~ s/^\/+//;
    foreach my $fileInfo (@{$files}) {
      my ($fileName) = @{$fileInfo};
      $file = $destDirRelativePath ? sprintf('%s/%s', $destDirRelativePath, $fileName) : $fileName;
      Logging::debug("Add file $file to archive");
      $self->{cmdInput} .= "$file\n";
      IPC::Run::pump($self->_getCmd());
    }
  };
  if ($@) {
    Logging::warning(sprintf('Unable to upload archive %s to FTP storage: %s', $file, $@));
    $self->_finishCmd();
  }
  return $ret;
}

sub _getCmd {
  my $self = shift;

  if (!$self->{cmd}) {
    my $command = [AgentConfig::pmmRasBin(), '--export-dump-as-file'];
    if ($self->{ftp}) {
      $ENV{'DUMP_STORAGE_PASSWD'} = $self->{ftp}->{password};
      push(@{$command}, '--dump-file-specification', sprintf('%s/%s', HelpFuncs::getStorageUrlFromFtpSettings($self->{ftp}), $self->{exportFileName}));
      push(@{$command}, '--use-ftp-passive-mode') if exists($self->{ftp}->{'passive'});
    } else {
      push(@{$command}, '--dump-file-specification', sprintf('%s/%s', $self->{exportDir}, $self->{exportFileName}));
    }
    push(@{$command}, '--dump-storage', sprintf('%s/%s', $self->{output_dir}, $self->{mainDumpRootPath}));
    push(@{$command}, '--split-size', $self->{split_size}) if $self->{split_size};
    push(@{$command}, '--session-path', $self->{sessionPath}) if $self->{sessionPath};
    push(@{$command}, '--debug', '--verbose') if $self->{verbose};
    Logging::debug('Start: ' . join(' ', @{$command}));
    $self->{cmd} = IPC::Run::start($command, \$self->{cmdInput}, \$self->{cmdOutput});
  }
  return $self->{cmd};
}

sub _finishCmd {
  my $self = shift;

  if ($self->{cmd}) {
    my @createdVolumes = ();
    eval {
      $self->{cmd}->finish() or die(sprintf('%s command completed with non-zero exit code %s', basename(AgentConfig::pmmRasBin()), $self->{cmd}->result()));
      @createdVolumes = split("\n", $self->{cmdOutput}) if $self->{cmdOutput};
    };
    if ($@) {
      Logging::warning(sprintf("Unable to upload backup files to FTP storage: %s\nSTDOUT: %s", $@, $self->{cmdOutput}));
    }
    $self->{cmd} = undef;
    $self->{cmdInput} = '';
    $self->{cmdOutput} = '';
    $self->{createdVolumes} = \@createdVolumes;
  }
}

1;
