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

abstract class DBInserter
{
  
  protected $dbw;

  
  protected $tableName;

  
  protected $dataModulFields;

  public function __construct($pDBWork, $pTableName, $pDataModulFields)
  {
    $this->dbw = $pDBWork;
    $this->tableName = $pTableName;
    $this->dataModulFields = $pDataModulFields;
  }

  public function insert($pDatamodul, $pIdFieldName = 'id', $pDontProtocol = false, $pDmzBetrieb = false)
  {
    $dbFieldValueMap = $this->getDbFieldValuesMap($pDatamodul, $pIdFieldName);
    if (empty($dbFieldValueMap)) {
      \Logger::logg('Einfügen in Tabelle ' . $this->tableName . ' fehlgeschlagen: Keine Felder übergeben', 514);

      return 0;
    }

    $this->dbw->dboperation->clear();
    $sql = 'INSERT INTO ' . $this->tableName
           . ' (' . $this->getFelderListe($dbFieldValueMap) . ') '
           . 'VALUES (' . $this->getSQLValuesListe($dbFieldValueMap) . ')';
    
    $this->dbw->dboperation->execute($sql);

    $id = $this->getIdAfterInsert($dbFieldValueMap, $pIdFieldName);
    $this->handleProtocol($dbFieldValueMap, $id, $pIdFieldName, $pDontProtocol, $pDmzBetrieb);

    return $id;
  }

  protected function handleProtocol($dbFieldValueMap, $id, $pIdFieldName, $pDontProtocol, $pDmzBetrieb)
  {
    if (!$pDontProtocol) {
      $this->dbw->saveChanging($this->tableName, '', '', $id, 'id', 'I', $pDmzBetrieb);
      foreach ($dbFieldValueMap as $dbFieldname => $values) {
        if ($dbFieldname != $pIdFieldName) {
          $this->dbw->saveChanging(
            $this->tableName,
            '', 
                $values['datamodulvalue'],
            $id,
            $dbFieldname,
            'A',
            $pDmzBetrieb
          );
        }
      }
    }
    $this->dbw->setActionIDs();
  }

  protected function getDbFieldValuesMap($pDatamodul, $pIdFieldName)
  {
    $dbFieldValueMap = array();
    foreach ($this->dataModulFields as $datamodulField) {
      $dbFieldname = $this->dbw->translateVarName($datamodulField);
      if ($dbFieldname == $pIdFieldName) {
        $dbFieldValueMap = $this->handleIdMap($dbFieldValueMap, $dbFieldname);
      } elseif ($dbFieldname == 'guid') {
        $dbFieldValueMap = $this->handleGuidMap($dbFieldValueMap, $pDatamodul);
      } else {
        $dbFieldValueMap = $this->handleFieldMap($dbFieldValueMap, $dbFieldname, $pDatamodul, $datamodulField);
      }
    }

    return $dbFieldValueMap;
  }

  private function handleFieldMap($dbFieldValueMap, $dbFieldname, $pDatamodul, $datamodulField)
  {
    if (!$this->dbw->canupdate($datamodulField)) {
      return $dbFieldValueMap;
    }
    $dbFieldValueMap[$dbFieldname] = array();
    
    $dbFieldValueMap[$dbFieldname]['sqlvalue'] = $this->dbw->getSQLValue($datamodulField, $pDatamodul);
    $dbFieldValueMap[$dbFieldname]['datamodulvalue'] = $pDatamodul->getVarValue($datamodulField);

    return $dbFieldValueMap;
  }

  
  private function handleGuidMap($dbFieldValueMap, $pDatamodul)
  {
    if (empty($pDatamodul->guid) || $pDatamodul->guid->isEmpty()) {
      $guid = \Kufer\Web\Classes\Addfunctions\Guid::generate();
    } else {
      $guid = $pDatamodul->getVarValue('guid');
    }
    $dbFieldValueMap['guid'] = array();

    $dbFieldValueMap['guid']['sqlvalue'] = $this->dbw->dboperation->getGuidForSql($guid);
    $dbFieldValueMap['guid']['datamodulvalue'] = $guid;

    return $dbFieldValueMap;
  }

  abstract protected function handleIdMap($dbFieldValueMap, $dbFieldname);

  abstract protected function getIdAfterInsert($dbFieldValueMap, $pIdFieldName);

  protected function getFelderListe($dbFieldValueMap)
  {
    return implode(', ', array_keys($dbFieldValueMap));
  }

  protected function getSQLValuesListe($dbFieldValueMap)
  {
    return implode(', ', $this->getSQLValues($dbFieldValueMap));
  }

  protected function getSQLValues($dbFieldValueMap)
  {
    return array_map(function($valueEintrag) {
      return $valueEintrag['sqlvalue'];
    }, $dbFieldValueMap);
  }
}

class DBInserterOhneGenTable extends DBInserter
{
  protected function handleIdMap($dbFieldValueMap, $dbFieldname)
  {
    
    return $dbFieldValueMap;
  }

  protected function getIdAfterInsert($dbFieldValueMap, $pIdFieldName)
  {
    return abs($this->dbw->dboperation->getLastID($this->tableName));
  }
}

class DBInserterMitGenTable extends DBInserter
{
  protected function handleIdMap($dbFieldValueMap, $dbFieldname)
  {
    
    
    $idfield = $this->dbw->dboperation->getString4Sql($dbFieldname);
    $id = $this->dbw->dboperation->getNextIDGen($this->tableName, $idfield);
    $dbFieldValueMap[$dbFieldname] = array();
    $dbFieldValueMap[$dbFieldname]['sqlvalue'] = "'" . $id . "'"; 
    $dbFieldValueMap[$dbFieldname]['datamodulvalue'] = $id;

    return $dbFieldValueMap;
  }

  protected function getIdAfterInsert($dbFieldValueMap, $pIdFieldName)
  {
    return abs($dbFieldValueMap[$pIdFieldName]['datamodulvalue']);
  }
}