<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

namespace Kufer\KuferTools\Oeffentlich\LoginAnfordern\Utils;

class NeuesLoginAnlegen
{
  private $undoByError = array();
  
  const NEUESLOGIN_SUCCESS = 1;
  const NEUESLOGIN_ERROR_ALLGEMEIN = 2;
  const NEUESLOGIN_ERROR_LOGIN_BEREITS_VORHANDEN = 3;
  const NEUESLOGIN_ERROR_OPTIN_NICHT_GEFUNDEN = 4; 
  
  public function neuesDozentenLoginperDmz($pLogin, $pName, $pVorname, $pPasswortHash, $pHashversion, $pEmail)
  {
    $login = \StringOperations::strtoupper($pLogin);
    
    if($this->loginBereitsVergeben($login)) {
      return self::NEUESLOGIN_ERROR_LOGIN_BEREITS_VORHANDEN;
    }
    
    $dozent = $this->insertDozent($pName, $pVorname, $pEmail);
    $webUser = $this->insertWebUser($login, $dozent->id);
    
    $message = $this->getXml4Dmz($dozent, $webUser);
    
    try {
      $abgleichAPI = new \AbgleichAPI();
      $dmzResult = $abgleichAPI->sendeNachricht(\AbgleichAPI::ABGLEICH_NEUES_DOZLOGIN, \SessionOperations::getUserID(), new \Nutzlast($message));
      if ($dmzResult->code != \AbgleichApiResult::CODE_SUCCESS) {
        $this->rewindNeusLogin();
        return self::NEUESLOGIN_ERROR_ALLGEMEIN;
      }
      
      $result = \JsonOperations::getFromString($dmzResult->reason);
      if (is_null($result) || !isset($result->loginWarBereitsVergeben) || !isset($result->dozentWurdeNeuAngelegt) || !isset($result->technischerFehler)) {
        $this->rewindNeusLogin();
        return self::NEUESLOGIN_ERROR_ALLGEMEIN;
      }
      
      if ($result->loginWarBereitsVergeben) {
        
        $this->rewindNeusLogin();
        return self::NEUESLOGIN_ERROR_LOGIN_BEREITS_VORHANDEN;
      } else if ($result->technischerFehler) {
        $this->rewindNeusLogin();
        return self::NEUESLOGIN_ERROR_ALLGEMEIN;
      } else {
        
        if(!$result->dozentWurdeNeuAngelegt) {
          
          $dozent = $this->getDozentObj($pName, $pVorname, $pEmail);
          $dozentFromDb = $this->getDozentFromDb($dozent);
          if($dozentFromDb != null && $dozentFromDb->id > 0) {
            
            
            $this->rewindNeusLogin();
            $webUser = $this->insertWebUser($login, $dozentFromDb->id);
          }
          
        }
        
        $this->insertWebToolsUsers($webUser->id);
        $this->insertPasswort($webUser, $pPasswortHash, $pHashversion);
        return self::NEUESLOGIN_SUCCESS;
      }

    } catch(\AbgleichApiException $aae) {
      \Logger::logg("Neues Dozentenlogin anlegen per DMZ - folgende Exception ist aufgetreten: ".$aae->getMessage()."\n".' ['.$aae->getTraceAsString().']', 200);
      $this->rewindNeusLogin();
      return self::NEUESLOGIN_ERROR_ALLGEMEIN;
    }
  }
  
  private function loginBereitsVergeben($pLogin)
  {
    $dbwWebUser = new \DBWorkUser(1, true);
    $webUser = $dbwWebUser->getUserbyLogin($pLogin);
    return $webUser != null && $webUser->id > 0;
  }
  
  private function getXml4Dmz($dozent, $webUser)
  {
    $dozXml = $dozent->ToXml(array(), true, array(), 'dozent');
    $webUserXml = $webUser->ToXml(array(), true, array(), 'web_user');
    $message = new \XMLNode('neues_doz_login');
    $message->addChild($dozXml);
    $message->addChild($webUserXml);
    return $message;
  }
  
  private function insertDozent($pName, $pVorname, $pEmail)
  {
    $dozent = $this->getDozentObj($pName, $pVorname, $pEmail);
    $undoableInsertDozent = $this->getUndoableInsertDozent($dozent);
    $dozentFromDb = $undoableInsertDozent->doOnce();
    $this->undoByError[] = $undoableInsertDozent;
    return $dozentFromDb;
  }
  
  private function getDozentObj($pName, $pVorname, $pEmail)
  {
    $dozent = new \Dozent();
    $dozent->setValue2Var('name', $pName);
    $dozent->setValue2Var('vorname', $pVorname);
    $dozent->setValue2Var('email', $pEmail);
    $dozent->setValue2Var('email_anzeige', $pEmail);
    return $dozent;
  }
  
  private function getDozentFromDb($dozentToSearch)
  {
    $dbwDozenten = new \DBWorkDozenten(1, true);
    $dbwDozenten->newSearch();
    $dbwDozenten->fromobject->name = $dozentToSearch->getVarValue('name');
    
    $dbwDozenten->fromobject->vorname = $dozentToSearch->getVarValue('vorname');
    $dozenten = $dbwDozenten->getDozenten();
    
    $dbwKommunikation = new \DBWorkKommunikation('D', 1, true);
    $dbwKommunikation->allkom = true;
    $dbwUser = new \DBWorkUser(1, true);
    foreach($dozenten as $dozent) {
      
      if(\StringOperations::strtolower(trim($dozent->getVarValue('name'))) == \StringOperations::strtolower(trim($dozentToSearch->getVarValue('name'))) && 
         \StringOperations::strtolower(trim($dozent->getVarValue('vorname'))) == \StringOperations::strtolower(trim($dozentToSearch->getVarValue('vorname')))) {
         
        $kommunikationen = $dbwKommunikation->getKommunikationByNrTypArt($dozent->getVarValue('id'), 'D', 'E');
        foreach($kommunikationen as $kommunikation) {
          if(\StringOperations::strtolower(trim($kommunikation->wert)) == \StringOperations::strtolower(trim($dozent->getVarValue('email_anzeige')))) {
            $logins = $dbwUser->getUsersByDnr($dozent->id);
            if(count($logins) == 0) {
              return $dozent;
            }
          }
        }
      }
    }
    return null;
  }
  
  private function getUndoableInsertDozent($dozent)
  {
    $dnr;
    $dbwDozenten = new \DBWorkDozenten(1, true);
    $dbwKommunikation = new \DBWorkKommunikation('D', 1, true);
    
    $doFunction = function() use ($dozent, &$dnr, $dbwDozenten) {
      $dozent->id = $dbwDozenten->insertDozent($dozent, \SessionOperations::getUserID());
      
      $dnr = $dozent->id;
      return $dbwDozenten->getDozent($dozent->id, true);
      return $dozent;
    };
    
    $undoFunction = function() use (&$dnr, $dbwDozenten, $dbwKommunikation) {
      $dbwDozenten->deleteDozent($dnr, \SessionOperations::getUserID());
      $kommunikationen = $dbwKommunikation->getKommunikationsblock($dnr);
      foreach($kommunikationen as $kommunikation) {
        $dbwKommunikation->deleteKommunikation($kommunikation, \SessionOperations::getUserID());
      }
      $dnr = 0;
    };
    
    return new \UndoAble($doFunction, $undoFunction);
  }
  
  private function getUndoableInsertWebUser($webUser)
  {
    $dbwWebUser = new \DBWorkUser(1, true);
    $wuId;
    
    $doFunction = function() use ($webUser, &$wuId, $dbwWebUser) {
      $webUser->id = $dbwWebUser->insertUser($webUser, \SessionOperations::getUserID(), true);
      
      $wuId = $webUser->id;
      return $webUser;
    };
    
    $undoFunction = function() use (&$wuId, $dbwWebUser) {
      $dbwWebUser->deleteWebUser($wuId, \SessionOperations::getUserID());
      $wuId = 0;
    };
    
    return new \UndoAble($doFunction, $undoFunction);
  }
  
  private function insertWebUser($login, $dnr)
  {
    $webUser = new \Benutzer();
    $webUser->dnr = $dnr;
    $webUser->login = $login;
    $webUser->admin = -1;
    $webUser->tnr = -1;
    $webUser->anr = -1;
    $webUser->ben = -1;
    
    $undoableInsertWebUser = $this->getUndoableInsertWebUser($webUser);
    $webUser = $undoableInsertWebUser->doOnce();
    $this->undoByError[] = $undoableInsertWebUser;
    
    return $webUser;
  }
  
  private function insertWebToolsUsers($userId)
  {
    $dbwWebToolsStdTempl = new \ DBWorkWebToolsStdTempl(1, true);
    $dbwWebToolsUsers = new \DBWorkWebToolsUsers(1, true);
    $webToolsStdTempl = $dbwWebToolsStdTempl->get4Doz();
    $wtus = array();
    foreach($webToolsStdTempl as $wtst) {
      $wtu = $this->getWebToolsUsers4Template($wtst, $userId);
      $wtu->id = $dbwWebToolsUsers->insertWebToolsUsers($wtu, \SessionOperations::getUserID(), true);
      $wtus[] = $wtu;
    }
    
    return $wtu;
  }
  
  private function getWebToolsUsers4Template($webToolsStdTempl, $userId)
  {
    $webToolsUsers = new \WebToolsUsers();
    $webToolsUsers->template_id = $webToolsStdTempl->template_id;
    $webToolsUsers->tool_id = $webToolsStdTempl->tool_id;
    $webToolsUsers->user_id = $userId;
    $webToolsUsers->validfrom = $webToolsStdTempl->validfrom;
    $webToolsUsers->validuntil = $webToolsStdTempl->validuntil;
    
    if($webToolsUsers->validfrom == '' || $webToolsUsers->validfrom == DEFAULTDATE) {
      $webToolsUsers->validfrom = \DateTimeOperations::getDateNow();
    }
    
    if($webToolsUsers->validuntil == '' || $webToolsUsers->validuntil == DEFAULTDATE) {
      $webToolsUsers->validuntil = '31.12.2099';
    }
    
    return $webToolsUsers;
  }
  
  private function insertPasswort($webUser, $pPasswortHash, $pHashversion)
  {
    $dbwUser = new \DBWorkUser(1, true);
    $dbwUser->setHashedPassWD($webUser->login, $pPasswortHash, $pHashversion);
  }
  
  private function rewindNeusLogin()
  {
    foreach($this->undoByError as $undoable) {
      $undoable->undo();
    }
  }
}