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

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

use ArchiveContent::UnixArchiveContent;

use vars qw|@ISA|;

sub new {
  my ($self, $storage, $packer) = @_;
  return ArchiveContent::UnixArchiveContent->new( $storage, $packer );
}

### Public routines ###
# addAdminContent,addResellerContent,addClientContent,addDomainContent,addPhostingContent,\
# addSubDomainContent,addSubDomainPhostingContent,addMailnameContent,addDbContent,addSubdomainDbContent

sub addAdminContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  return $self->_addTar( $cid_type, $self->{packer}->getAdminBackupPath( $file ) , @_);
}

sub addResellerContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  return $self->_addTar( $cid_type, $self->{packer}->getResellersBackupPath($id, $file ), @_);
}

sub addClientContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  return $self->addResellerContent( $cid_type, $id, $file, @_ ) if defined ($self->{packer}->{resellersNodes}) and exists $self->{packer}->{resellersNodes}->{$id};
  return $self->_addTar( $cid_type, $self->{packer}->getClientsBackupPath($id, $file ), @_);
}

sub addDomainContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  return $self->_addTar( $cid_type, $self->{packer}->getDomainsBackupPath($id, $file ), @_);
}

sub addPhostingContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $referralId = shift;
  my $file = shift;
  
  my $domainId = $self->{packer}->getPhostingParentId( $referralId );
  my $referer;
  # do not allow referred cid creation to user-data archive, otherwise user-data archive itself will not be restored
  if (exists $self->{packer}->{domainVhost}->{$domainId} && $self->{packer}->{domainVhost}->{$domainId}->[0] != 'user-data') {
    $referer = $self->_getDomainPhTarReferer($domainId, @_);
    $referer = $self->_getDomainStatTarReferer($domainId, @_) unless defined $referer;
  }
  if( defined $referer ) {
    return $self->_addRefererCid( $referer , $cid_type);
  }
  else{
    return $self->_addTar( $cid_type, $self->{packer}->getPhostingBackupPath($id, $file ), @_);
  }
}

sub addSubDomainContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  return $self->_addTar( $cid_type, $self->{packer}->getSubdomainsBackupPath($id, $file ), @_);
}

sub addSubDomainPhostingContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $referralId = shift;
  my $file = shift;
  my $referer;
  if( $referralId ) {
    $referer = $self->_getDomainPhTarReferer( $referralId, @_ );
    unless( defined $referer) {
      $referer = $self->_getDomainPhTarReferer( $self->{packer}->getSubdomainParentId( $id ), @_ );
    }
  }
  if( defined $referer ) {
    return $self->_addRefererCid( $referer , $cid_type );
  }
  else {
    return $self->_addTar( $cid_type, $self->{packer}->getSubdomainsBackupPath($id, $file ), @_);
  }
}

sub addMailnameContent{
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  my $file = shift;
  my $referrer = $self->_getDomainMailTarReferer( $self->{packer}->getMailNameParentId( $id ), @_ );
  if( defined $referrer ){
    return $self->_addRefererCid( $referrer, $cid_type );
  }
  else {
    return $self->_addTar( $cid_type, $self->{packer}->getMailnamesBackupPath($id, $file ), @_);
  }
}

sub addDbContent {
  my $self = shift;
  my $cid_type = shift;
  my $id = shift;
  return $self->_addDb( $cid_type, $self->{packer}->getDatabasesBackupPath( $id, '' ), @_);
}

sub addSubdomainDbContent {
  my $self = shift;
  my $cid_type = shift;
  my $subdomainId = shift;
  my $id = shift;
  return $self->_addDb( $cid_type, $self->{packer}->getSubdomainsBackupPath( $subdomainId, "db$id" ), @_);
}

sub getContentTransportDescription {
  return undef;
}

sub _getTarReferer{
  my( $self, $referrer, %options ) = @_;
  if( $referrer && exists $options{'directory'} ) {
    my $directory = HelpFuncs::convertPathToUnixFormat($options{'directory'});
    return undef unless -d $directory;
    my $referrerDir = HelpFuncs::convertPathToUnixFormat($referrer->[2]);
    
    if( index( $directory, $referrerDir ) == 0 ){
      my @res;
      my $ref = substr( $directory, length($referrerDir) );
      while( index( $ref, '/' )==0 ) {
        $ref = substr( $ref, 1 );
      }
      push @res, $referrer->[1];
      push @res, $ref;
      push @res, $directory;
      return \@res;
    }
  }
  return;
}

sub _getDomainMlTarReferer{
  my $self = shift;
  my $domainId = shift;
  if (exists $self->{packer}->{domainMailListContent}->{$domainId} ) {
    return $self->_getTarReferer( \@{$self->{packer}->{domainMailListContent}->{$domainId}}, @_ );
  }
  return;
}

sub _getDomainPhTarReferer{
  my $self = shift;
  my $domainId = shift;
  if (exists $self->{packer}->{domainVhost}->{$domainId} ) {
    return $self->_getTarReferer( \@{$self->{packer}->{domainVhost}->{$domainId}}, @_ );
  }
  return;
}

sub _getDomainStatTarReferer{
  my $self = shift;
  my $domainId = shift;
  if (exists $self->{packer}->{domainStatistics}->{$domainId} ) {
    return $self->_getTarReferer( \@{$self->{packer}->{domainStatistics}->{$domainId}}, @_ );
  }
  return;
}

sub _getDomainMailTarReferer{
  my $self = shift;
  my $domainId = shift;
  if (exists $self->{packer}->{domainMailContent}->{$domainId} ) {
    return $self->_getTarReferer( \@{$self->{packer}->{domainMailContent}->{$domainId}}, @_ );
  }
  return;
}

sub _addRefererCid{
  my ($self, $referer, $cid_type ) = @_;
  return unless defined $referer;
  Logging::debug( "Add referrer cid for type '$cid_type', referer '$referer->[1]', from path '$referer->[2]'" );

  my $cid = XmlNode->new( 'cid' );
  $cid->setAttribute( 'type', $cid_type );
  $cid->setAttribute( 'unpacksize', $referer->[0]->getAttribute( 'unpacksize' ) );
  $cid->setAttribute( 'path', $referer->[0]->getAttribute( 'path' ) );
  $cid->setAttribute( 'referrer', 'true' );
  $cid->setAttribute( 'offset', $referer->[1] );
  my @files = $referer->[0]->getChildren( 'content-file' );
  foreach my $file(@files) {
    if ($file) {
      $cid->addChild( XmlNode->new( 'content-file', 'content' => $file->getText(), 'attributes' => {'size' => $file->getAttribute('size')}));
    }
  }
  return $cid;
}

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

  if (exists($options{'skip_content'})) {
    return $options{'skip_content'} ? 1 : 0;
  } else {
    return exists($self->{packer}->{skip_content}) ? 1 : 0;
  }
}

1;