package SiteApp::SiteApp10;

use strict;
use XmlNode;
use Logging;
use AgentConfig;

sub getSappMetas {
  my ($webspaceId, $getSappsInstancesUtilFunc) = @_;

  if( defined ($getSappsInstancesUtilFunc) && !(ref($getSappsInstancesUtilFunc)=~/CODE/ ) ) {
    Logging::error( "Unable to dump APS instances. APS instances util is not specified." ,'UtilityError');
    return;
  }

  my $sappsArrayDef = _getSappsArrayDef($webspaceId, defined( $getSappsInstancesUtilFunc ) ? $getSappsInstancesUtilFunc : \&getSappsInstancesUtil);
  return unless defined $sappsArrayDef;

  my $sappsArray = _getSappsArray($sappsArrayDef);
  return unless defined $sappsArray;

  return _getSappInstalledXmlNodes($sappsArray);
}

sub _hash2SappXmlNode {
  my $hashPtr = shift;
  return unless ( ref($hashPtr) =~ /HASH/ );

  my %hash = %{$hashPtr};

  my $name = $hash{'_name'};
  return unless defined $name;

  my $xmlNode = XmlNode->new( $name );
  if ( defined ( $hash{'_value'} ) and ( $hash{'_value'} ne '' ) ) {
    $xmlNode->setText( $hash{'_value'} );
  }

  if ( defined ( $hash{'_attrs'} ) and ( ref ( $hash{'_attrs'} ) =~ /HASH/ ) ) {
    my %attrs = %{$hash{'_attrs'}};
    foreach my $attrName ( keys %attrs ) {
      $xmlNode->setAttribute( $attrName, $attrs{$attrName} ) if defined $attrs{$attrName};
    }
  }

  if ( defined ( $hash{'_children'} ) and ( ref ( $hash{'_children'} ) =~ /ARRAY/ ) ) {
    my @children = @{$hash{'_children'}};
    foreach my $child ( @children ) {
      next unless ( ref( $child ) =~ /HASH/ );
      my $childXmlNode = _hash2SappXmlNode($child);
      $xmlNode->addChild($childXmlNode) if defined $childXmlNode;
    }
  }

  $xmlNode;
}

sub _getSappInstalledXmlNodes {
  my $sappsArray = shift;

  my @sapps = @{$sappsArray};
  my @sappInstalledXmlNodes;

  foreach my $sapp (@sapps) {
    my $xmlNode = _hash2SappXmlNode($sapp);
    if ( defined $xmlNode ) {
      push @sappInstalledXmlNodes, $xmlNode;
    }
  }

  return @sappInstalledXmlNodes;
}

sub _getSappsArray {
  my $input = shift;
  my $sappsArrayDef = $input;

  my @sapps_installed;
  eval $sappsArrayDef;
  if ( $@ ) {
    Logging::error( "Unable to parse APS definition from utility output ($@):\n $input", 'UtilityError' );
    return;
  }

  return \@sapps_installed;
}

sub getSappsInstancesUtil {
  my $webspaceId  = shift;
  my $cmd = AgentConfig::apsInstancesUtil() . " --get-web-space-instances " . $webspaceId;
  Logging::info("Exec: $cmd");
  return $cmd;
}

sub _getSappsArrayDef {
  my $webspaceId  = shift;
  my $getSappsInstancesUtilFunc = shift;

  unless( ref($getSappsInstancesUtilFunc)=~/CODE/ ) {
    Logging::error( "Unable to dump APS instances. APS instances util is not specified." ,'UtilityError');
    return;
  }
  my $cmd = $getSappsInstancesUtilFunc->($webspaceId);
  my $result = `$cmd`;
  chomp($result);

  my $retCode = $? >> 8;
  if( $retCode != 0 ) {
    Logging::error( "Unable to get APS instances on webspace id $webspaceId (ErrorCode: $retCode, STDOUT:$result)." ,'UtilityError');
    return;
  }

  return $result;
}

sub new( $ )
{
  my $class = shift;

  my $self = {};
  bless($self, $class);

  $self->{sappXmlNode} = shift;

  if (ref($self->{sappXmlNode}) =~ /XmlNode/ ) {
    my $vhost = $self->{sappXmlNode}->getChild( 'vhost' );
    if ( defined $vhost ) {
        my $name = $vhost->getChild( 'name' );
        $self->{siteName} = $name->getText() if defined $name;

        my $type = $vhost->getChild( 'type' );
        $self->{siteType} = $type->getText() if defined $type;

        my $id = $vhost->getChild( 'id' );
        $self->{siteId} = $id->getText() if defined $id;
    }
  }

  return $self;
}

sub getName
{
  my $self = shift;
  return $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-name')->getText();
}

sub getVersion
{
  my $self = shift;

  my $sappVersionNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-version');
  if (defined $sappVersionNode ) {
    return $sappVersionNode->getText();
  }
  return;
}

sub getRelease
{
  my $self = shift;

  my $sappReleaseNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-release');
  if (defined $sappReleaseNode ) {
    return $sappReleaseNode->getText();
  }
  return;
}

sub getDescription
{
  my $self = shift;

  my $sappDescriptionNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-description');
  if (defined $sappDescriptionNode ) {
    return $sappDescriptionNode->getText();
  }
  return;
}

sub isCommercial
{
  my $self = shift;

  my $sappCommercialNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-commercial');
  if (defined $sappCommercialNode ) {
    return $sappCommercialNode->getText();
  }
  return;
}

sub isIntegrated
{
  my $self = shift;

  my $sappIntegratedNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-integrated');  
  if (defined $sappIntegratedNode ) {
    return $sappIntegratedNode->getText();
  }
  return;
}

sub getSappPackageId
{
  my $self = shift;

  my $sappPackageIdNode = $self->{sappXmlNode}->getChild('sapp-spec')->getChild('sapp-package-id');
  if (defined $sappPackageIdNode ) {
    return $sappPackageIdNode->getText();
  }
  return;
}



sub encodedParams
{
  my $self = shift;
  return 1;
}

# Returns %hash
sub getParams
{
  my $self = shift;

  my %params;

  my @sappParamNodes = $self->{sappXmlNode}->getChildren('sapp-param');
  if ( @sappParamNodes ) {
    foreach my $sappParamNode ( @sappParamNodes ) {
      my $sappParamName = $sappParamNode->getChild('sapp-param-name')->getText();
      my $sappParamValue = $sappParamNode->getChild('sapp-param-value')->getText();
      $params{ $sappParamName } = $sappParamValue;
    }
  }
  return \%params;
}

# Returns @list
sub getDatabases
{
  my $self = shift;

  my @databases;

  my @databaseNodes = $self->{sappXmlNode}->getChildren('database');
  if ( @databaseNodes ) {
    foreach my $databaseNode ( @databaseNodes ) {
      my $id = $databaseNode->getAttribute('id');
      push @databases, { 'id' => $id, 'param' => undef, 'apsRegistryId' => $databaseNode->getAttribute('aps-registry-id'), 'apsCreatedUser' => $databaseNode->getAttribute('user')};
    }
  }
  return @databases;
}

sub getCustomButtons
{
  my $self = shift;
  return;
}

sub getInstallPrefix
{
  my $self = shift;
  return $self->{sappXmlNode}->getChild('sapp-installdir')->getChild('sapp-prefix')->getText();
}

sub isDomainSiteapp
{
  my $self = shift;
  my $domainName = shift;
  return ($self->{siteType} eq 'hosting') && ($self->{siteName} eq $domainName);
}

sub isSubdomainSiteapp( $ )
{
  my $self = shift;
  my $subdom_id = shift;

  return ( ($self->{siteType} eq 'subdomain') && ($self->{siteId}==$subdom_id) );
}

sub isSsl
{
  my $self = shift;

  my $sappSslNode = $self->{sappXmlNode}->getChild('sapp-installdir')->getChild('sapp-ssl');
  if (defined $sappSslNode ) {
    return 1;
  }
  return;
}

sub getHtdocsFiles
{
  my $self = shift;
  my @htdocsFiles = ();
  return \@htdocsFiles;
}

sub getCgibinFiles
{
  my $self = shift;
  my @cgibinFiles = ();
  return \@cgibinFiles;
}

sub getAPSClientItemLicenseType
{
  my $self = shift;
  return;
}

sub getEntryPoints
{
  my $self = shift;
  my @sappEntryPointsNodes = $self->{sappXmlNode}->getChildren('sapp-entry-point');

  my @eps;
  if (@sappEntryPointsNodes) {
    foreach my $epNode (@sappEntryPointsNodes) {
      my %ep;

      $ep{'label'} = $epNode->getChild('label')->getText();
      $ep{'description'} = $epNode->getChild('description')->getText();
      $ep{'hidden'} = $epNode->getChild('hidden')->getText();
      $ep{'http'} = $epNode->getChild('http')->getText();
      $ep{'icon'} = $epNode->getChild('icon')->getText() if defined $epNode->getChild('icon');

      my $permissionNode = $epNode->getChild('limits-and-permissions')->getChild('permission');
      $ep{'permission-name'} = $permissionNode->getAttribute('name');
      $ep{'permission-class'} = $permissionNode->getAttribute('class');

      push @eps, \%ep;
    }
  }
  return @eps;
}

sub getContext
{
  my $self = shift;
  my $context = $self->{sappXmlNode}->getChild('context');
  if ( defined $context ) {
    return $context->getAttribute('type');
  }
  return;
}

sub getApplicationApsRegistryId
{
  my $self = shift;
  my $apsregistryIdNode = $self->{sappXmlNode}->getChild('aps-registry-id');
  if ( defined $apsregistryIdNode ) {
    return $apsregistryIdNode->getText();
  }
  return;
}

sub getInstallDirApsRegistryId
{
  my $self = shift;
  my $installDirNode = $self->{sappXmlNode}->getChild('sapp-installdir');
  if ( defined $installDirNode ) {
    my $installDirApsRegistryIdNode = $installDirNode->getChild('aps-registry-id');
    if ( defined $installDirApsRegistryIdNode ) {    
      return $installDirApsRegistryIdNode->getText();
    }
  }
  return;
}

sub getBackupArchiveFile
{
  my $self = shift;
  my $backupArchiveFileNode = $self->{sappXmlNode}->getChild('backup-archive-file');
  if ( defined $backupArchiveFileNode ) {
    return $backupArchiveFileNode->getText();
  }
  return;
}

sub isContainLicense
{
  my $self = shift;
  my $licenseNode = $self->{sappXmlNode}->getChild('sapp-license');
  if ( defined $licenseNode ) {
    return 1;
  }
  return;
}

sub getLicenseApsRegistryId
{
  my $self = shift;
  my $licenseNode = $self->{sappXmlNode}->getChild('sapp-license');
  my $apsRegistryNode = $licenseNode->getChild('aps-registry-id');
  if ( defined $apsRegistryNode ) {
    return $apsRegistryNode->getText();
  }
  return;
}

sub getLicenseType
{
  my $self = shift;
  my $licenseNode = $self->{sappXmlNode}->getChild('sapp-license');
  my $licenseTypeNode = $licenseNode->getChild('license-type');
  if ( defined $licenseTypeNode ) {
    return $licenseTypeNode->getText();
  }
  return;
}

sub getActivationCode
{
  my $self = shift;
  my $licenseNode = $self->{sappXmlNode}->getChild('sapp-license');
  my $activationCodeNode = $licenseNode->getChild('activation-code');
  if ( defined $activationCodeNode ) {
    return $activationCodeNode->getText();
  }
  return;
}
1;
