<?php

namespace Modules\Orders\ImportedOrders\Webservice\Model\ExecOperation;

class ImportOrder extends GeneralAbstract
{
	/**
	 * Stores the decoded file content
	 * @var String
	 */
	private $fileContentDecoded = NULL;

	/**
	 * Stores the importe order object
	 * @var \App\ImportedOrder\Order
	 */
	private $importedOrder = NULL;

	/**
	 * (non-PHPdoc) Checks if username and token are valid
	 * @see \Modules\Orders\ImportedOrders\Webservice\Model\ExecOperation\GeneralAbstract::checkRequest()
	 */
	protected function checkRequest()
	{
		// validate mandatory fields
		if (!$this->request->fileContent || !$this->request->fileSize || !$this->request->fileContentChecksum) {
			throw new \RuntimeException('File content, file size and file content checksum are mandatory.');
		}

		// validate file content
		$fileContentDecoded = base64_decode($this->request->fileContent);
		if ($fileContentDecoded === FALSE) {
			throw new \RuntimeException('The file content is not base64_encoded.');
		}
		$this->fileContentDecoded = $fileContentDecoded;

		// validate if the fileContent is XML valid
		$fileContentXML = @simplexml_load_string($fileContentDecoded, '\Engine\SimpleXmlElement');
		if (!$fileContentXML) {
			throw new \RuntimeException('The file content is not XML valid.');
		}

		// validate file size
		if (strlen($fileContentDecoded) != $this->request->fileSize) {
			throw new \RuntimeException("The size of the decoded file content is not the same with the one in the request.");
		}

		// valide checksum
		if (crc32($fileContentDecoded) != $this->request->fileContentChecksum) {
			throw new \RuntimeException("Invalid checksum.");
		}

		// validate imported order
		try {
			$importedOrderParser = new \App\ImportedOrder\Parser\Xml_V20($fileContentXML);
			$importedOrderParser->createImportedOrder();
			$importedOrder = $importedOrderParser->getImportedOrder();
			$this->importedOrder = $importedOrder;
		}
		catch (\App\MessagesException $ex) {
			throw new \RuntimeException(sprintf("Invalid imported order. Error message: %s.", $ex->getMessagesCollector()->getMessageBulk()));
		}

		//check if username and token are
		$idExternalSystem = \Entity\ExtResSystem::getSystemIdByCode($this->importedOrder->externalSystemCode);
		if (!$idExternalSystem) {
			throw new \RuntimeException("Invalid external system code.");
		}

		$extResSystemEntity = \Entity\ExtResSystem::select($idExternalSystem);
		if ($extResSystemEntity->username != $this->request->username) {
			throw new \RuntimeException("Username is not associated with the external system code from request.");
		}
	}


	/**
	 * (non-PHPdoc)
	 * @see \Modules\Orders\ImportedOrders\Webservice\Model\ExecOperation\GeneralAbstract::executeRequestedOperation()
	 */
	protected function executeRequestedOperation()
	{
		try {
			\DB::startTransaction();

			// import the order
			$importedOrderEntity = \Entity\ImportedOrder::insert();
			$importedOrderEntity->order = $this->importedOrder;
			$importedOrderEntity->applyMode = 'merge';
			$importedOrderEntity->originalFilesContent = [
				[
					'content' => 	$this->fileContentDecoded,
					'name' => 		'importedOrder.xml'
				]
			];
			$importedOrderEntity->save();

			\DB::commitTransaction();

			$this->response->idImportedOrder = $importedOrderEntity->getId();
		}
		catch (\App\Entity\Exception $ex) {
			\DB::rollbackTransaction();
			throw new \RuntimeException(sprintf("Cannot import order. Error message: %s.", $ex->getMessageBulk()));
		}
	}
}