<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

class DBConnectionInfo
{
  private const FIELDS_TO_ENCODE = array(
    'db_server',
    'db_name',
    'db_user',
    'db_password',
    'db2_server',
    'db2_name',
    'db2_user',
    'db2_password'
  );

  
  public $configDir = '';

  public $db_typ = DBTypeEnum::MYSQLI;
  public $db_server = '';
  public $db_name = '';
  public $db_user = '';
  public $db_password = '';

  public $db_replikat = true;
  public $db_fastheader = true;
  public $db_hybrid = false;
  public $db_isEncodingUtf8 = false;
  public $db_setClientBufferMaxKBSize = 0;

  public $db2_typ = '';
  public $db2_server = '';
  public $db2_name = '';
  public $db2_user = '';
  public $db2_password = '';

  public function __construct($pAutoLoad = true)
  {
    $this->configDir = ConstantOperations::getPathForCoreSettings();

    if (function_exists('mysqli_connect')) {
      $this->db_typ = DBTypeEnum::MYSQLI;
    }

    
    if ($pAutoLoad) {
      $this->readConnectionInfo();
    }
  }

  
  public static function getInstance()
  {
    static $instance = null;

    if ($instance === null) {
      $instance = new DBConnectionInfo();
    }

    return $instance;
  }

  
  private function createConnectPhpByCfg()
  {
    $this->readConnectCfg();
    $connectPhpCreated = $this->writeConnectPhp();

    if ($connectPhpCreated) {
      $this->renameConnectCfg();
    }

    return $connectPhpCreated;
  }

  
  public function writeConnectPhp()
  {
    $fileName = $this->configDir . 'connect.php';

    $result = "<?php\n";

    $resultEncoding = \CodingOperations::getAllgsettingsEncoding();

    $createEntry = static function(string $key, $value) {
      return '  $' . $key . " = $value;\n";
    };

    $createEntryString = static function(string $key, string $value) use ($createEntry) {
      $value = \str_replace("'", "\\'", $value);

      return $createEntry($key, "'$value'");
    };

    $result .= $createEntryString('file_encoding', $resultEncoding);

    
    $aryVars = get_object_vars($this);
    foreach ($aryVars as $varName => $value) {
      if ((StringOperations::strpos($varName, 'db_') !== false) || ((StringOperations::strpos($varName, 'db2_') !== false) && $this->db_hybrid)) {
        if (is_bool($value)) {
          $result .= $createEntry($varName, $value ? 'true' : 'false');
        } elseif (in_array($varName, static::FIELDS_TO_ENCODE)) {
          $result .= $createEntryString($varName, \mb_convert_encoding($value, $resultEncoding, \CodingOperations::getInternalEncoding()));
        } else {
          $result .= $createEntryString($varName, $value);
        }
      }
    }

    $result .= '?>';

    

    $fileWork = new SimpleFileWork();
    $fileWork->filename = $fileName;
    $fileWork->access = 'w';
    $fileWork->content = $result;
    $fileWork->openFile();
    $fileWork->setContent();
    $fileWork->closeFile();

    return file_exists($fileName);
  }

  
  public function readConnectionInfo()
  {
    
    
    if (!file_exists($this->configDir . 'connect.php')) {
      if (file_exists($this->configDir . 'connect.cfg')) {
        
        
        if (!$this->createConnectPhpByCfg()) {
          $this->readConnectCfg();
        } else {
          $this->readConnectPhp();
        }
      }
    } else {
      
      $this->readConnectPhp();
    }
  }

  
  private function readConnectPhp()
  {
    
    
    
    require $this->configDir . 'connect.php';

    $this->db_typ = $db_typ;
    $this->db_server = $db_server;
    $this->db_name = $db_name;
    $this->db_user = $db_user;
    $this->db_password = $db_password;

    $this->db_replikat = $db_replikat;
    $this->db_fastheader = $db_fastheader;
    $this->db_hybrid = $db_hybrid;
    $this->db_isEncodingUtf8 = $db_isEncodingUtf8 ?? false;
    $this->db_setClientBufferMaxKBSize = $db_setClientBufferMaxKBSize ?? 0;

    if ($this->db_hybrid) {
      $this->db2_typ = $db2_typ;
      $this->db2_server = $db2_server;
      $this->db2_name = $db2_name;
      $this->db2_user = $db2_user;
      $this->db2_password = $db2_password;
    } else {
      $this->copyDbInfo();
    }

    
    
    
    
    if (file_exists($this->configDir . 'connect.cfg')) {
      $this->renameConnectCfg();
    }

    if (isset($file_encoding)) {
      $convertToInternal = \FunctionOperations::argsWithPlaceholder('\\mb_convert_encoding', \FunctionOperations::placeholder(), \CodingOperations::getInternalEncoding(), $file_encoding);
      foreach (static::FIELDS_TO_ENCODE as $field) {
        $this->{$field} = $convertToInternal($this->{$field});
      }
    }
  }

  
  private function readConnectCfg()
  {
    $fp = fopen($this->configDir . 'connect.cfg', 'r');
    $this->db_typ = trim(str_replace('db_typ:', '', fgets($fp, 1024)));
    $this->db_server = trim(str_replace('db_server:', '', fgets($fp, 1024)));
    $this->db_name = trim(str_replace('db_name:', '', fgets($fp, 1024)));
    $this->db_user = trim(str_replace('db_user:', '', fgets($fp, 1024)));
    $this->db_password = trim(str_replace('db_password:', '', fgets($fp, 1024)));

    $this->db_replikat = trim(str_replace('db_replikat:', '', fgets($fp, 1024))) == 'true';
    $this->db_fastheader = trim(str_replace('fastheader:', '', fgets($fp, 1024))) == 'true';

    
    
    
    trim(str_replace('xmlanmeldung:', '', fgets($fp, 1024))); 
    $this->db_hybrid = trim(str_replace('zweidbs:', '', fgets($fp, 1024))) == 'true';

    
    if ($this->db_hybrid) {
      $this->db2_typ = trim(str_replace('db2_typ:', '', fgets($fp, 1024)));
      $this->db2_server = trim(str_replace('db2_server:', '', fgets($fp, 1024)));
      $this->db2_name = trim(str_replace('db2_name:', '', fgets($fp, 1024)));
      $this->db2_user = trim(str_replace('db2_user:', '', fgets($fp, 1024)));
      $this->db2_password = trim(str_replace('db2_password:', '', fgets($fp, 1024)));
    } else { 
      $this->copyDbInfo();
    }

    fclose($fp);

    foreach (static::FIELDS_TO_ENCODE as $field) {
      $this->{$field} = mb_convert_encoding($this->{$field}, \CodingOperations::getInternalEncoding(), CP1252);
    }
  }

  private function renameConnectCfg()
  {
    $configFile = $this->configDir . 'connect.cfg';

    

    $fileWork = new SimpleFileWork();
    $fileWork->filename = $configFile;
    $fileWork->getContent();
    $content = $fileWork->content;

    
    $fileWork->filename = $configFile . '.php';
    $fileWork->access = 'w';
    $fileWork->content = "<?php\n \$content = '" . $content . "'\n?>";
    $fileWork->openFile();
    $fileWork->setContent();
    $fileWork->closeFile();
    if (!file_exists($configFile . '.php')) {
      $msg = 'Die Datei "connect.cfg.php" konnte nicht erstellt werden! Bitte '
             . 'prüfen Sie die Verzeichnis- und Dateirechte!';
      die($msg);
    }

    
    if (!unlink($configFile)) {
      $msg = 'Die Datei "connect.cfg" konnte nicht gelöscht werden! Bitte '
             . 'prüfen Sie die Verzeichnis- und Dateirechte!<br />'
             . 'Aus Sicherheitsgründen muss diese Datei gelöscht werden!';
      die($msg);
    }
  }

  
  private function copyDbInfo()
  {
    $this->db2_typ = $this->db_typ;
    $this->db2_server = $this->db_server;
    $this->db2_name = $this->db_name;
    $this->db2_user = $this->db_user;
    $this->db2_password = $this->db_password;
  }
}