# Copyright 1999-2016. Parallels IP Holdings GmbH. All Rights Reserved.
package LegacyDomainUserDumper;

use strict;
use CommonPacker;
use Logging;

my %domainUserAttribute = ( 'contact' => 'personalName', );

my %domainUserInfo = (
  'company' => 'companyName',
  'phone'   => 'phone',
  'fax'     => 'fax',
  'address' => 'address',
  'city'    => 'city',
  'state'   => 'state',
  'zip'     => 'zip',
  'email'   => 'email',
  'country' => 'country',
);

my %locale_map = (
  'bg' => 'bg',
  'hk' => 'zh-HK',
  'ru' => 'ru-RU',
  'en' => 'en-US',
  'nl' => 'nl-NL',
  'br' => 'pt-BR',
  'it' => 'it-IT',
  'tr' => 'tr-TR',
  'es' => 'es-ES',
  'pl' => 'pl-PL',
  'ca' => 'ca-ES',
  'jp' => 'ja-JP',
  'tw' => 'zh-TW',
  'fi' => 'fi-FI',
  'cn' => 'zh-CN',
  'ko' => 'ko-KR',
  'fr' => 'fr-FR',
  'pt' => 'pt-PT',
  'de' => 'de-DE',
  'lt' => 'lt-LT'
);

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

sub _init {
  my ( $self, $pleskX ) = @_;
  $self->{dbh} = $pleskX->{dbh};
  $self->{packer} = $pleskX->{packer};
  $self->{xmlPermissions} = $pleskX->getXmlPermissions();
}

sub makeDomainUserNode {
  my ( $self, $domainId, $domParams ) = @_;

  my ( $sql, $item, $ptrHash, $xmlName, $fieldName );

  $sql = "SELECT * FROM dom_level_usrs WHERE dom_id=?";
  unless ( $self->{dbh}->execute_rownum($sql, $domainId) ) {
    $self->{dbh}->finish();
    return undef;
  }
  my %domainUser = %{ $self->{dbh}->fetchhash() };
  $self->{dbh}->finish();

  my $state;
  if ( $domainUser{'state'} ) {
    $state = $domainUser{'state'};
  }

  my $passwd;
  my $passwdType;
  
  if ( defined $domainUser{'account_id'}
    and $domainUser{'account_id'} != 0 )
  {
    ( $passwd, $passwdType ) = $self->makeAccountPasswordNode( $domainUser{'account_id'} );
  }  

  if ( defined( $domainUser{'card_id'} ) ) {
    $sql = "SELECT * from Cards WHERE id=?";
    if ( $self->{dbh}->execute_rownum($sql, $domainUser{'card_id'}) ) {
      $ptrHash = $self->{dbh}->fetchhash();
    }
    $self->{dbh}->finish();
  }

  my $locale = $self->getDomainUserLocale($domainId);

  $self->addDomainUser( $domainId, $passwd, $passwdType, $state, $locale, $ptrHash );
  
  $self->addPermissions( $domainId, $domainUser{'perm_id'} );
  
  $self->addDomainUserMultipleLoginPermission($domainId, $domParams->{'multiply_login'} ) if defined $domParams and exists $domParams->{'multiply_login'};
}

sub getDomainUserLocale {
  my ( $self, $domainId ) = @_;

  my $locale = "locale";

  my $sql = "SELECT val FROM dom_param WHERE dom_id = ? AND param = '?'";
  my $ptrRow;
  if ( $self->{dbh}->execute_rownum($sql, $domainId, $locale)
    && ( $ptrRow = $self->{dbh}->fetchrow() ) )
  {
    if ( $ptrRow->[0] ) {
      my ( $key, $value );
      while ( ( $key, $value ) = each(%locale_map) ) {
        if ( $ptrRow->[0] eq $key ) {
          $ptrRow->[0] = $value;
        }
      }

      $locale = $ptrRow->[0];
    }
    $self->{dbh}->finish();

    return $locale;
  }

  return undef;
}

sub addDomainUserMultipleLoginPermission {
  my ( $self, $id, $multiple_sessions ) = @_;

 # Old plesks have bug when mn_param table contains 1 instead of 'true'. Fixing.
 $multiple_sessions = 'true' if $multiple_sessions eq '1';
 $self->addDomainPermission( $id, 'multiple-sessions', $multiple_sessions eq 'true' ? 'true' : 'false' );
}

sub addDomainUser {
  my ( $self, $domainId, $passwd, $passwdType, $state, $locale, $paramsPtr) = @_;

  my %params = %{$paramsPtr};

  my $parent = $self->{packer}->{domainNodes}->{$domainId};
  if (!defined($parent) ) {
    printToError('Error: addDomainUser: empty parent node');
    return;
  }

  my $root = XmlNode->new('domainuser');

  if ( $state ) {
    $root->setAttribute( 'status', $state );
  }

  if (defined($passwd)) {
      $root->addChild( CommonPacker::makePasswordNode( $passwd, $passwdType ) );
  }
  while ( my ( $xmlName, $fieldName ) = each %domainUserAttribute ) {
    if ( $params{$fieldName} ) {
      $root->setAttribute( $xmlName, $params{$fieldName} );
    }
  }

  while ( my ( $xmlName, $fieldName ) = each %domainUserInfo ) {
    my $value = $params{$fieldName};
    if ($value) {
      $value = CommonPacker::normalizeCountry($value) if $fieldName eq 'country';
      $root->addChild(
        XmlNode->new(
          'pinfo',
          'content'    => $value,
          'attributes' => { 'name' => $xmlName }
        )
      );
    }
  }

  $root->addChild(
    XmlNode->new(
      'pinfo',
      'content'    => $locale,
      'attributes' => { 'name' => 'locale' }
    )
  ) if defined $locale;


  $parent->addChild($root);
}

sub _makePasswordData{
  my ($password, $type) = @_;

  if (!defined $password) {
    Logging::warning( "'undef' password passed to _makePasswordData. Change to empty!" );
    $password = '';
  }

  if (!$password) {
    $type = 'plain';
  }
  return ($password, $type);
}

my $tableAccounts = undef;

sub makeAccountPasswordNode {
  my ( $self, $accountId ) = @_;

  my ( $passwd, $type );
  my %values;

  if( not defined $tableAccounts ){
    if ( $self->{dbh}->execute( "SELECT id, password, type FROM accounts" ) ) {
       while( my $ptrRow = $self->{dbh}->fetchrow() ){
         $values{$ptrRow->[0]} = ();
         push @{$values{$ptrRow->[0]}}, $ptrRow->[1];
         push @{$values{$ptrRow->[0]}}, $ptrRow->[2];
      }
    }
    $self->{dbh}->finish();
    $tableAccounts = \%values;
  }

  if ( exists $tableAccounts->{$accountId} )
  {
    ( $passwd, $type ) = @{$tableAccounts->{$accountId}};
    ( $passwd, $type ) = _makePasswordData( $passwd, CommonPacker::normalizePasswordType($type) );
  }
  else {

    # generates a stub node
    ( $passwd, $type ) = _makePasswordData();
  }
  $self->{dbh}->finish();

  return ( $passwd, $type );
}

sub addPermissions {
  my ( $self, $parent, $id ) = @_;
  my ( $sql, $ptrRow, $item, $name, $value );

  $sql = "SELECT permission,value FROM Permissions WHERE id=?";

  if ( $self->{dbh}->execute_rownum($sql, $id) ) {
    while ( $ptrRow = $self->{dbh}->fetchrow() ) {
      $name  = $ptrRow->[0];
      $value = $ptrRow->[1];
      $name  = "manage_virusfilter" if $name eq "manage_drweb";      

	  next unless exists $self->{xmlPermissions}->{$name};
	  
      if ( $name eq 'make_dumps' ) {
        $self->addDomainPermission( $parent, 'allow_local_backups', $value );
        $self->addDomainPermission( $parent, 'allow_ftp_backups',   $value );
        next;
      }

      $self->addDomainPermission( $parent, $name, $value );
    }
  }
  $self->{dbh}->finish();

  $sql = "SELECT value FROM Permissions WHERE id = ? and ("
        . "permission = 'ipb_allow' or permission = 'nb_allow')";
  if ( $self->{dbh}->execute_rownum($sql, $id) ) {
    my $value = @{ $self->{dbh}->fetchrow() }[0];
    $self->addDomainPermission( $parent, 'manage_phosting', $value );
  }
  $self->{dbh}->finish();
}

sub addDomainPermission {
  my ( $self, $domainId, $name, $value ) = @_;

  my $root = $self->{packer}->{domainNodes}->{$domainId};

  my @domainUsers = $root->getChildren('domainuser');
  if ( scalar(@domainUsers) < 1 ) {
    Logging::warning('Error: addDomainPermission: there are no node "domainuser"');
    return;
  }

  $self->{packer}->makePermissionNode( $domainUsers[0], $name, $value );
}

1;
