<?php
namespace Entity;

class SabreFile extends \App\Entity\GeneralAbstract
{

	/**
	 * Indicate if the operations available for the current entity must be done inside a transaction or not.
	 * @var Boolean
	 */
	protected $saveInsideTransaction = true;

	/**
	 * Indicate how many seconds the external cache is valid. 0 for unlimited, -1 for no cache.
	 * @var Int
	 */
	const cacheTtl=604800;	// 60*60*24*7

	protected $tablePrimaryKey = 'idFile';
	protected $primaryKeyType = 'string';

	/**
	 * (non-PHPdoc)
	 * @see \App\Entity\SelectAbstract::setTableName()
	 */
	protected function setTableName(): void
	{
		global $DBTSabreParsedFiles;
		$this->tableName = $DBTSabreParsedFiles;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Entity\SelectAbstract::getAttribute()
	 */
	protected function getAttribute($var)
	{

		// CHECK EVERY POSSIBLE VALUES THAT $var MAY HAVE -----------------------------------------
		switch ($var) {
			// serialized fields
			case 'filePath': {
				$filePath = $this->fields['filePath'];
				return $filePath;
			}
			case 'relativeFilePath': {
				return $this->fields['filePath'];
			}

			// the original parsed file content
			case 'parsedFile': {
				$cacheKey = sprintf("%s-%s-%s", __METHOD__, $var, $this->getId());
				$data=\Engine\Cache\General::getInstance('disk')->get($cacheKey);
				if (!$data) {
					$data = $this->getAttribute('parsedFileParser')->getExtractedData();
					\Engine\Cache\General::getInstance('disk')->set($cacheKey, $data, self::cacheTtl);
				}

				return $data;
			}

			// the parsedFile parser
			case 'parsedFileParser': {
				$fileParser = new \App\Sabre\FileParser\IUR();

				global $CFG;
				if ($this->getAttribute('filePath')[0]=='/') {
					$filePath = realpath($this->getAttribute('filePath'));
				}
				else {
					$filePath = realpath(MODULE_REL_PATH.$CFG['paths']['sabre'].$this->getAttribute('filePath'));
				}

				$fileParser->setRawData(file_get_contents($filePath));
				$fileParser->setStoredData('fileDate', min($fileParser->collectFileDatesFromPath($filePath)));
				$fileParser->extract();
				return $fileParser;
			}

			case 'parsedFileProcessor': {
				$processor = new \App\Sabre\StructureParser\Processor($this->getAttribute('parsedFileParser'));
				$processor->setFile($this->getAttribute('filePath'));
				$processor->initialize();
				return $processor;
			}

			// expand the list of ids of imported orders
			case 'idImportedOrders' :
				return explodeClean("|", $this->fields[$var]);
			break;

			// addUser
			case 'addUser': {
				return \Entity\User::select($this->fields['idAddUser'], $this->selectForUpdate);
			}

			// updateUser
			case 'updateUser': {
				return \Entity\User::select($this->fields['idUpdateUser'], $this->selectForUpdate);
			}

			// the rest of the fields (most of them are just copied)
			default: {
				return parent::getAttribute($var);
			}
		}

	}


	/**
	 * (non-PHPdoc)
	 * @see \App\Entity\GeneralAbstract::setAttribute()
	 */
	protected function setAttribute($var, $value)
	{

		if ($this->operation!='insert' and $this->operation!='update') {
			throw new \Exception('You can call '.__METHOD__.' only for insert/update operations.');
		}

		switch ($var) {
			// simple fields
			case 'idFile':
			case 'source':
			case 'idImportedOrders':
			case 'IP':{
				$this->fields[$var]=$value;
				break;
			}

			case 'filePath': {
				global $CFG;
				$filesPath = realpath(MODULE_REL_PATH.$CFG['paths']['sabre']).'/';

				if (!\Engine\Dir::check(MODULE_REL_PATH.$CFG['paths']['sabre'])) {
					throw new \Exception(sprintf("Dir::check(%s) returned false", MODULE_REL_PATH.$CFG['paths']['sabre']));
				}

				$filePath = realpath($value);
				$this->fields[$var] = str_replace($filesPath, '', $filePath);
				break;
			}

			// the field is not valid
			default: {
				throw new \Exception("The field '$var' is not valid for the `".__CLASS__."` entity.");
			}
		}
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Entity\GeneralAbstract::save_finalSaveData()
	 */
	protected function save_finalSaveData(Array $saveData)
	{
		if ($this->operation == 'insert') {
			$saveData['addTime'] =  DATETIME;
			$saveData['idAddUser']= CURRENT_ID_USER;
		}

		return $saveData;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Entity\GeneralAbstract::save_filterSaveData()
	 */
	protected function save_filterSaveData(Array $saveData)
	{
		if ($saveData['idImportedOrders']) {
			$saveData['idImportedOrders'] = '|'.implode('|', array_filter($saveData['idImportedOrders'])).'|';
		}
		return $saveData;
	}
}
