<?php
namespace Modules\Orders\Galileo\Collector;

class Model extends \ModulesAbstract\ImportedOrdersFileManager\Model
{
	/**
	 * (non-PHPdoc)
	 * @see \ModulesAbstract\ImportedOrdersFileManager\Model::createConvertInputToFilters()
	 */
	public function createConvertInputToFilters()
	{
		return new \Modules\Orders\Galileo\Collector\Model\ConvertInputToFilters();
	}

	/**
	 * (non-PHPdoc)
	 * @see \ModulesAbstract\ImportedOrdersFileManager\Model::getFileParsedData()
	 */
	public function getFileParsedData($fileFullPath)
	{
		$fileParser = $this->buildFileParser($fileFullPath);
		return [
			'extractedData' => 	$fileParser->getExtractedData(),
			'fileId' =>			$fileParser->getFileId(),
			'messages' =>		$fileParser->getMessagesCollector(),
		];
	}

	/**
	 * Build file parser object
	 * @param String $fileFullPath
	 * @return \App\Galileo\FileParser\MIR
	 */
	private function buildFileParser($fileFullPath)
	{
		$fileParser = new \App\Galileo\FileParser\MIR();
		$fileParser->setMessagesCollector(new \App\MessagesCollector());
		$fileParser->setRawData(\Engine\File::getContents($fileFullPath));

		// exceptions might get thrown in the following few lines
		$fileParser->extract();

		return $fileParser;
	}

	/**
	 * (non-PHPdoc)
	 * @see \ModulesAbstract\ImportedOrdersFileManager\Model::getStructureParserData()
	 */
	public function getStructureParserData($fileFullPath)
	{
		$processor = $this->buildStructureParser($fileFullPath);

		return [
			'transactions' => 			$processor->getSortedTransactions(),
			'messages' =>				$processor->getMessagesCollector(),
			'fileId' =>					$processor->getFileParser()->getFileId(),
			'fileParserMessages' =>		$processor->getFileParser()->getMessagesCollector(),
			'generalAssociations'=> 	$processor->getInternalAssociations(),
		];
	}

	private function buildStructureParser($fileFullPath)
	{
		$fileParser = $this->buildFileParser($fileFullPath);

		// use the processor to process the raw data
		$processor = new \App\Galileo\StructureParser\Processor($fileParser);
		$processor->initialize();
		$processor->setFile($fileFullPath);

		return $processor;
	}

	public function parseFile($fileFullPath)
	{
		$processor = $this->buildStructureParser($fileFullPath);

		// store the parsed data
		$storage = new \App\Galileo\Storage\StorageHandler();
		$storage->setProcessor($processor);
		$storage->setOption('source', "manual");
		$storage->setOption('IP', $_SERVER['REMOTE_ADDR']);
		$ret = $storage->execute();

		// determine what entities were inserted, reselect from DB, and insert them
		$entities = [];
		if ($ret['inserted']) {
			foreach ($ret['inserted'] as $entityId) {
				$entities[] = \Entity\GalileoService::select($entityId);
			}
			if ($entities) {
				$convertor = new \App\Galileo\CompatibilityWithImportedOrders\Processor($entities);
				$order = $convertor->getConvertedOrder();
				$applyMode = $convertor->getConvertedApplyMode();

				$orderInsert = \Entity\ImportedOrder::insert();
				$orderInsert->applyMode = $applyMode;	// overwrite, merge
				$orderInsert->order = $order;

				$orderInsert->originalFilesWithPath = [$this->getFilePathRelativeToFilesRoot($fileFullPath)];
				$orderInsert->save();

				$insertedOrderId = $orderInsert->getId();

				// collect a list of affected files, and update their `idImportedOrders` field with the current $insertedOrderId
				// step 1: collect affected files. I'd expect that only one file gets filled in here, but one never knows
				$affectedFiles = [];
				foreach($entities as $ent) {
					$affectedFiles[$ent->idFile] = $ent->file;
				}

				// step 2: update their corresponding field
				foreach($affectedFiles as $file) {
					$fileUpd = \Entity\GalileoFile::update($file->getId());
					$idImportedOrders = $file->idImportedOrders;
					$idImportedOrders[] = $insertedOrderId;
					$fileUpd->idImportedOrders = $idImportedOrders;
					$fileUpd->save();
				}
			}

			$processor->getFileParser()->destroyCCInformationAndWriteInto($fileFullPath);
		}
	}
}