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


class IniFile
{
  
  public $filename = '';

  protected $keysToValues = array();

  
  protected $keysToRealKeys = array();

  private function openFileContent($filename)
  {
    if (!is_readable($filename)) {
      return '';
    }

    $content = file_get_contents($filename);

    $encoding = CP1252;
    $encodingPraeffix = mb_convert_encoding('encoding=', 'ASCII');
    if (\StringOperations::startsWith($content, $encodingPraeffix)) {
      $encodingValueStart = \StringOperations::strlen($encodingPraeffix, 'ASCII');
      $encodingValueEndCRLF = \StringOperations::strpos($content, "\r", $encodingValueStart, 'ASCII');
      $encodingValueEndLF = \StringOperations::strpos($content, "\n", $encodingValueStart, 'ASCII');
      $encodingValueEnd = $encodingValueEndCRLF === false ? $encodingValueEndLF : min($encodingValueEndLF, $encodingValueEndCRLF);
      $encoding = \StringOperations::substr($content, $encodingValueStart, $encodingValueEnd - $encodingValueStart, 'ASCII');
      $content = \StringOperations::substr($content, $encodingValueEnd + 2, null, 'ASCII');
    }

    $encodeSettings = new EncodeCharset4Allgsettings($encoding);

    return $encodeSettings->encode($content);
  }

  
  public function openFile($filename)
  {
    $this->filename = $filename;
    $fehlerzeile = '';
    $content = $this->openFileContent($this->filename);
    $lineSeparator = "\r\n";
    if (strpos($content, $lineSeparator) === false) {
      $lineSeparator = "\n";
    }
    $lines = \StringOperations::explodeGenerator($lineSeparator, $content);
    unset($content); 

    $i = 0;
    foreach ($lines as $line) {
      $line = \trim($line);
      if ($line !== '') {
        $ary = \explode('=', $line, 2); 
        if (count($ary) !== 2) {
          $fehlerzeile = $i;
        } else {
          list($key, $value) = $ary;
          $this->setValueToKey($key, $value);
        }
      }

      $i++;
    } 

    return $fehlerzeile;
  }

  
  public function closeFile()
  {
    if (\StringOperations::endsWith($this->filename, 'allgeinstell.cfg')) {
      $vhsname = $this->getValueByKey('vhsname', '');
      if ($vhsname === '') {
        Logger::logg('allgeinstell wird geschrieben, aber vhsname ist leer!'
          . ' SessionOperations::isWebadminEingeloggt(): |' . SessionOperations::isWebadminEingeloggt() . '| URL:' . DebugOperations::getVollstaendigeAufgerufeneURL() . ' Backtrace: ' . DebugOperations::getBackTrace(), 500);
      }
    }
    if (!is_writable($this->filename)) {
      return false;
    }

    $filehandle = fopen($this->filename, 'w');
    if ($filehandle === false) {
      return false;
    }

    $encodeSettings = new EncodeCharset4Allgsettings();
    
    if (fwrite($filehandle, mb_convert_encoding('encoding=' . $encodeSettings->getFromEncoding() . "\r\n", 'ASCII')) === false) {
      return false;
    }
    foreach ($this->keysToValues as $key => $value) {
      if (trim($key) != '') {
        $strtowrite = $this->keysToRealKeys[$key] . '=' . $value . "\r\n";
        $strtowrite = $encodeSettings->decode($strtowrite);
        if (fwrite($filehandle, $strtowrite) === false) {
          return false;
        }
      }
    }
    $this->filename = '';

    return fclose($filehandle);
  }

  
  public function getValueByKey($key, $default = '')
  {
    $key = StringOperations::strtoupper($key);
    if (\array_key_exists($key, $this->keysToValues)) {
      return $this->keysToValues[$key];
    }

    return $default;
  }

  
  public function setValueToKey($key, $value)
  {
    $aryKey = \StringOperations::strtoupper($key);
    if (\array_key_exists($aryKey, $this->keysToValues)) {
      $this->keysToValues[$aryKey] = $value;
    } else {
      $this->keysToValues[$aryKey] = $value;
      $this->keysToRealKeys[$aryKey] = $key;
    }
  }

  
  public function hasKey(string $key)
  {
    return \array_key_exists($key, $this->keysToValues);
  }

  
  public function getKeys(): array
  {
    return \array_values($this->keysToRealKeys);
  }

  
  public function setValuesToKeys($keyAry, $valueAry)
  {
    foreach ($keyAry as $k => $key) {
      $this->setValueToKey($keyAry[$k], $valueAry[$k]);
    }
  }

  
  public function set(array $ary): void
  {
    foreach ($ary as $key => $value) {
      $this->setValueToKey($key, $value);
    }
  }
}