<?php

/**
 * Vychozí třída pro exporty.
 *
 * @category Dalten
 * @package  Export
 */
abstract class Dalten_Export_AbstractExport
{
	/**
	 * Číselníky.
	 *
	 * @var Serenity_Config_Config
	 */
	protected $_codebooks;

    /**
     * Definice entit.
     *
     * @var Serenity_Config_Config
     */
    protected $_entities;

	/**
	 * Zpracovatel hodnot.
	 *
	 * @var Dalten_Config_Processer_ProcesserInterface
	 */
	protected $_processer;

	/**
	 * Konstruktor.
	 *
	 * @param Serenity_Config_Config                          $codebooks Číselníky.
	 * @param Serenity_Config_Config                          $entities  Definice entit.
	 * @param Dalten_Config_Processer_ProcesserInterface|null $processer Zpracovatel hodnot.
	 *
	 */
	public function __construct(
        Serenity_Config_Config $codebooks,
        Serenity_Config_Config $entities,
        ?Dalten_Config_Processer_ProcesserInterface $processer = null)
    {
		$this->_codebooks = $codebooks;
		$this->_entities = $entities;
		$this->_processer = ($processer)
            ? $processer
            : new Dalten_Config_Processer_DefaultProcesser($codebooks);
	}

	/**
	 * Umožňuje exportu upravit položky ještě před jejich převedením pomocí processeru..
	 *
	 * @param mixed  $values     Pole hodnot entity.
	 * @param string $config     Definice entity.
	 * @param string $entityName Název entity.
	 *
	 * @return array Výsledné pole hodnot.
	 */
	protected function _format(array $values, $config, $entityName)
	{
		return $values;
	}

	/**
	 * Umožňuje exportu upravit položky po jejich převedení pomocí processeru..
	 *
	 * @param array  $convertedValues Pole převedených hodnot entity.
	 * @param array  $originalvalues  Pole původních (nepřevedených) hodnot entity.
	 * @param string $entityName      Název entity.
	 *
	 * @return array Výsledné pole hodnot.
	 */
	protected function _convert(array $convertedValues, array $originalvalues, $entityName)
	{
		return $convertedValues;
	}

	/**
	 * Převede hodnoty entity do formátu cíle exportu.
	 *
	 * @param string $name   Název entity
	 * @param array  $values Hodnoty entity.
	 *
	 * @return array Pole hodnot.
	 *
     * @throws Dalten_Export_Exception_UnknownEntity Pokud entita neexistuje.
     * @throws Dalten_Export_Exception_TypeMissing   Pokud není specifikován typ položky.
	 */
	protected function _formatEntityValues($name, array $values)
	{
        $name = (string) $name;
        if (!isset($this->_entities->$name)) {
            $message = "Entita s názvem '$name' nenalezena.";
            throw new Dalten_Export_Exception_UnknownEntity($message);
        }

        $config = $this->_entities->$name;
		foreach ($values as $key => $value) {
            if (empty($config->$key->type)) {
                $message = "U položky '$key' chybí typ (vlastnost type).";
                throw new Dalten_Export_Exception_TypeMissing($message);
            }
		}

		return (array) $this->_format($values, $config, $name);
	}

	/**
	 * Převede hodnoty entity na pole hodnot ve formátu vhodném pro export.
	 *
	 * @param string $name   Název entity.
	 * @param array  $values Hodnoty entity.
	 * @param object $config Konfigurace exportu.
	 *
	 * @return array Výsledné pole hodnot.
	 */
	public function convertEntityValues($name, array $values, $config)
	{
		$intersect = array_intersect_key($values, (array) $config);
		$values = array_merge($values, $this->_formatEntityValues($name, $intersect));

		$convertedValues = $this->_processer->processValues($values, $config);
		return $this->_convert($convertedValues, $values, $name);
	}
}
