# Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
package ExtensionPackage;

use strict;
eval{require warnings;1;};
use XmlNode;
use Data::Dumper;
use Logging;
use AgentConfig;
use ExtensionPackageMessage;

my $agent;

sub init {
  $agent = shift;
  return;
}

sub getExtensionPackage {
  my ($filter) = @_;
  
  my $extensionPackage;
  
  my $cmd = AgentConfig::getBackupRestoreHelperUtil();
  $cmd .= " --get-extension-package ";
  
  my $filterString = $filter->serialize();
  
  Logging::debug( "Exec: echo '$filterString' | " . $cmd . "|");
  
  unless(open( EXTPACK, "echo '$filterString' | " . $cmd . "|" )) {
    use Data::Dumper;
    Logging::warning("There was an error while trying to get data from Panel");
    Logging::debug("Command " . $cmd . " failed with input: " . Data::Dumper::dumper($filter));
    return undef;
  }
  
  binmode EXTPACK;
  while (<EXTPACK>) {
    $extensionPackage .= $_;
  }
  close(EXTPACK);
  
  eval {require XML::Simple; 1;};
  my $xs = XML::Simple->new(ForceArray => 1, RootName => '');
  my $extensionPackageXml = eval { $xs->XMLin($extensionPackage, KeyAttr => []) };

  unless ($extensionPackageXml) {
    Logging::warning("Not valid XML document is returned from Panel Business Logic");
    Logging::debug("Not valid XML document is returned from Panel Business Logic: " . $extensionPackage . " Additional info:". $@);
    return undef;
  }
  
  return $extensionPackageXml;
}

sub createFilterForExtensionPackage {
  my ($type, $name) = @_;
  
  my $filterNode = XmlNode->new('filter');
  
  # create settings node
  my $settingsNode = XmlNode->new('settings');
  my $typeNode = XmlNode->new('type');
  if ($agent->{configuration_dump}) {
    $typeNode->setText('configuration');
  } else {
    $typeNode->setText('full');
  }
  $settingsNode->addChild($typeNode);
  $filterNode->addChild($settingsNode);
  
  # create objects node
  my $objectsNode = XmlNode->new('objects');
  my $objectNode = XmlNode->new('object');
  $objectNode->setAttribute('uuid', $type . '#' . $name);
  
  # create services node
  my $servicesNode = XmlNode->new('services');
  
  if ( $agent->{only_mail_dump} ) {
    $servicesNode->setAttribute('filter-policy', 'include');
    my $mailServiceNode = XmlNode->new('service', 'attributes' => {'name' => 'mail'});
    $servicesNode->addChild($mailServiceNode);
  } elsif ( $agent->{only_hosting_dump} ) {
    $servicesNode->setAttribute('filter-policy', 'include');
    my $hostingServiceNode = XmlNode->new('service', 'attributes' => {'name' => 'hosting'});
    $servicesNode->addChild($hostingServiceNode);
  } else {
    $servicesNode->setAttribute('filter-policy', 'all');
  }
  
  $objectNode->addChild($servicesNode);
  $objectsNode->addChild($objectNode);
  $filterNode->addChild($objectsNode);
  
  return $filterNode;
}

# Method removes nodes 'instructions' and 'log' from all levels and returns remained information
sub getData {
  my ($extensionPackageXml) = @_;
  
  foreach my $object (@{$extensionPackageXml->{object}}) {
    delete $object->{'instructions'};
    delete $object->{'log'};
    foreach my $service (@{$object->{'service'}}) {
      delete $service->{'instructions'};
      delete $service->{'log'};
      foreach my $resource (@{$service->{'resource'}}) {
        delete $resource->{'instructions'};
        delete $resource->{'log'};
      }
    }
  }
  
  eval {require XML::Simple; 1;};
  my $xs = XML::Simple->new(ForceArray => 1, SuppressEmpty => '', RootName => '');
  
  return $xs->XMLout($extensionPackageXml);
}

#
# Methods returns following data structure  { 'uuid' => [ExtensionMessage1, ExtensionMessage2, ..., ExtensionMessageN] }
#
sub getLogs {
  my ($extensionPackageXml) = @_;
  
  my (%resultInfo);
    
  foreach my $object (@{$extensionPackageXml->{object}}) {
    $resultInfo{$object->{'uuid'}} = _getMessages($object->{'log'});
    foreach my $service (@{$object->{'service'}}) {
      $resultInfo{$service->{'uuid'}} = _getMessages($service->{'log'});
      foreach my $resource (@{$service->{'resource'}}) {
        $resultInfo{$resource->{'uuid'}} = _getMessages($resource->{'log'});
      }
    }
  }
  
  return \%resultInfo;
}

sub _getMessages {
  my ($log) = @_;
  
  my @resultMessages;
  
  foreach my $messages (@{$log}) {
    foreach my $message (@{$messages->{'message'}}) {
      push @resultMessages, ExtensionPackageMessage->new($message);
    }
  }
  
  return \@resultMessages;
}

1;