<?php
namespace App\Galileo\NDCLineParser\Types;

/**
 * Data line
 * DAS line, Dynamic Ancillary Services, they are used to specify ancillary services purchased for a booking
 * @author Lucian Sirbu
 */
class Data_AncillariesLCC extends \App\Galileo\LineParser\Types\GalileoBase
{
    // NOTE: be VERY careful about the following regexp, it needs to be as specific as possible in order to NOT match the Ancillaries data lines
    protected $extractRegexp = "/^(?P<rawData>FT-#TAS[0-9]+#DAS\/P[0-9\-\,\.]+\/S[0-9\-\,\.]+\/.+)/";
    protected $useCustomRegexp = true;

	protected $children_generic = [
		'key' => 			'custom',
		'description' => 	'Custom',

		[ 'key'=>'FT',  	                     'type'=>'Constant',        			 'val'=> 'FT-',                           'label'=>'DOCI-FREETEXT-#' ],
		[ 'key'=>'TAS',                          'type'=>'Constant',                     'val'=> '#TAS', ],
		[ 'key'=>'fareNumber',                   'type'=>'Integer',          'len' => 2, ],
		[ 'key'=>'separator',                    'type'=>'Constant',                     'val'=> '#', ],

		[ 'key'=>'DAS',                          'type'=>'Constant',                     'val'=> 'DAS', ],
		[ 'key'=>'passengerIdentifier',          'type'=>'Constant',                     'val'=> '/P', ],
		[ 'key'=>'passengerIdentifier',          'type'=>'Integer', ],
		[ 'key'=>'segmentNumber',                'type'=>'Constant',                     'val'=> '/S', ],
		[ 'key'=>'segmentNumber',                'type'=>'Integer', ],
		[ 'key'=>'separator',                    'type'=>'Constant',                     'val'=> '/', ],
		[ 'key'=>'rawData',                		 'type'=>'StringRaw', ],
	];

    protected function _extract(\App\Utils\BaseParser\TextParser\ExtractedBlock $ret, $originalRawData)
	{
		\Engine\Debug\ParserCallTrace\ParserCallTrace::getInstance()->logCallStart($this, __METHOD__, func_get_args());

		$m = $this->safeMatch($this->extractRegexp, $originalRawData);
		$this->rawData = $m->matches['rawData'];

		$ret->remainingGlobalData = substr($originalRawData, strlen($this->rawData));

		$extracted = false;

		// NOTE: if you want to define new formats, parse them at this point. The generic format is the fallback, and will extract the remaining data, making sure at least the price is in there

		// generic formats
		if (!$extracted) {
			$extracted = $this->_extractFromChildren_galileo($this->children_generic, $ret, $this->rawData);
			if ($extracted) {
				$dataStr = $ret->extractedData['rawData'];
				$ret->extractedData['_type'] = '01';
				$ret->extractedData['_description'] = 'generic format';
				$ret->extractedData['service'] = 			'';
				$ret->extractedData['unitCost'] = 			0.0;
				$ret->extractedData['serviceQuantity'] = 	1;
				$ret->extractedData['serviceCode'] = 		null;
				$ret->extractedData['serviceCode2'] = 		null;
				$ret->extractedData['serviceCode'] = 		null;
				$ret->extractedData['seat'] = 				null;
				$ret->extractedData['baggage'] = 			null;

				$xtr = $this->getExtractor();
				if ($m = $xtr->findAndStore("/(?P<service>.+)\/(?P<unitCost>[0-9]+\.[0-9]+)\/(?P<serviceQuantity>[0-9]+)$/", $dataStr)) {
					$extracted = true;
					$ret->extractedData['service'] = 			$m->service;
					$ret->extractedData['unitCost'] = 			$m->getFloat('unitCost');
					$ret->extractedData['serviceQuantity'] = 	$m->getInt('serviceQuantity');
				}
				elseif ($m = $xtr->findAndStore("/(?P<service>.+)\/(?P<unitCost>[0-9]+\.[0-9]+)$/", $dataStr)) {
					$extracted = true;
					$ret->extractedData['service'] = 			$m->service;
					$ret->extractedData['unitCost'] = 			$m->getFloat('unitCost');
				}

				// parse service, extract relevant info, assume "service" is in the format "code2-code"
				if ($m = $xtr->findAndStore("/^(.*)-(?P<serviceCode>.+)$/", $ret->extractedData['service'])) {
					$ret->extractedData['serviceCode'] = 		substr($m->serviceCode, 0, 2);
					$ret->extractedData['serviceCode2'] = 		trim(substr($m->serviceCode, 2));
				}
				// parse service, extract relevant info, assume "service" is in the format "code", this is the "compact format", with seat number
				elseif ($m = $xtr->findAndStore("/^((.*)?)\/(?P<serviceCode>.+)$/", $ret->extractedData['service'])) {
					$ret->extractedData['serviceCode'] = 		substr($m->serviceCode, 0, 2);
					$ret->extractedData['serviceCode2'] = 		trim(substr($m->serviceCode, 2));
				}
				// parse service, extract relevant info, assume "service" is in the format "code", this is the "compact format"
				elseif ($m = $xtr->findAndStore("/^(?P<serviceCode>.+)$/", $ret->extractedData['service'])) {
					$ret->extractedData['serviceCode'] = 		substr($m->serviceCode, 0, 2);
					$ret->extractedData['serviceCode2'] = 		trim(substr($m->serviceCode, 2));
				}

				// parse based on service code
				switch ($ret->extractedData['serviceCode']) {
					case 'SA': // seat assignment
						$ret->extractedData['_serviceLabel'] = 'Seat Assignment';
						if ($ms = $xtr->findAndStore("/^(?P<seat>[^\/]+)/", $ret->extractedData['service'])) {
							$ret->extractedData['seat'] = $ms->seat;
						}
					break;

					case 'BG': // baggage
						$ret->extractedData['_serviceLabel'] = 'Baggage';
						if ($ms = $xtr->findAndStore("/(?P<baggage>[0-9]+KG)$/", $ret->extractedData['service'])) {
							$ret->extractedData['baggage'] = $ms->baggage;
						}
					break;

					case 'TS': // fast track
						$ret->extractedData['_serviceLabel'] = 'Fast Track';
					break;

				}
			}
		}

		if (!$extracted) {
			\Engine\Debug\ParserCallTrace\ParserCallTrace::getInstance()->logCallEnd();
			throw new \App\Utils\BaseParser\TextParser\Exception\MissingRequiredElementException("Don't know how o parse this Remarks line. No defined format matches it", null, null, $this);
		}

		\Engine\Debug\ParserCallTrace\ParserCallTrace::getInstance()->logCallEnd();
		return $ret;
	}
}
