<?php
namespace App\Amadeus\FileParser;

class Line_RM extends \App\Amadeus\FileParser\LineAbstract
{
	/**
	 * 4.156. RM PNR Remarks
	 * see page 378(420)
	 *
	 * In this pseudo EDIFACT segment no separators are used.
	 * The 'segment' will be terminated by a Carriage Return.
	 * For those offices with AIR version 200 or above, the inclusion of these lines will be governed
	 * by an indicator in the office profile record
	 */
	protected $structure = [
		['name'=> 'MSGTAG',  'val' => 'RM',    'type' => 'AN',      'req' => 'M',  'len' => 2,],  // 1 : Message Tag (RM)
		['name'=> 'RMTYPE',                    'type' => 'AN',      'req' => 'M',  'len' => 1,],  // 2 : Remark types : a * identifies an accounting remark, a blank identifies a general remark
		['name'=> 'PNRRMK',                    'type' => 'AN',      'req' => 'M',],               // 3 : Remark text
		['name'=> 'XLINEASS','val' => '/L',    'type' => 'ASSOC',],
		['name'=> 'SEGASS',  'val' => ';S',    'type' => 'ASSOC',],
		['name'=> 'PSGASS',  'val' => ';P',    'type' => 'ASSOC',],
	];

	/**
	 * Get a structure by looking for its name
	 * @param string $name
	 * @return array|NULL
	 */
	protected function getStructByName($name)
	{
		foreach($this->structure as $struct) {
			if($struct['name']==$name) {
				return $struct;
			}
		}

		return null;
	}

	/**
	 * Check if a strcture name is available
	 * @param string $name
	 * @return boolean
	 */
	protected function hasStructByName($name)
	{
		return (bool)$this->getStructByName($name);
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Amadeus\FileParser\LineAbstract::parse()
	 */
	public function parse()
	{
		/*
		 * seems that the RM field can contain ';', so we need a custom parser in here
		 * @see BG/USIT/2011-10-15_164431_78.128.52.153__AIR00116.Txt
		 *
		 * This parser is also used by other line parsers (Line_RC for now), thats why its done in a more flexible manner
		 */

		$matches = [];

		// build a regex string according to the internal defined structure
		$regex = "/^";
		$regex.= "(?P<MSGTAG>{$this->structure[0]['val']})";
		if($this->hasStructByName('RMTYPE')) {
			$regex.= "(?P<RMTYPE>(\s|\*))";
		}

		if($this->hasStructByName('PNRRMK')) {
			$regex.= "(?P<PNRRMK>.*?)";
		}
		elseif($this->hasStructByName('INTRM')) {
			$regex.= "(?P<INTRM>.*?)";
		}

		if($this->hasStructByName('XLINEASS')) {
			$struct = $this->getStructByName('XLINEASS');
			$startTag = $struct['val'];
			$regex.= "(?P<XLINEASS>".preg_quote($startTag, '/')."[0-9-,]+(?=(;|$)))?";
		}

		if($this->hasStructByName('SEGASS')) {
			$regex.= "(?P<SEGASS>\;S[0-9-,]+)?";
		}
		if($this->hasStructByName('PSGASS')) {
			$regex.= "(?P<PSGASS>\;P[0-9-,]+)?";
		}
		$regex.= "$/";

		// do the actual custom regexp, to extract tags in a custom way
		preg_match($regex, $this->content, $matches);

		// write the tags into the internal tree
		$this->tree['MSGTAG'] = $matches['MSGTAG'];
		if($this->hasStructByName('RMTYPE')) {
			$this->tree['RMTYPE'] = $matches['RMTYPE'];
		}

		if($this->hasStructByName('PNRRMK')) {
			$this->tree['PNRRMK'] = $matches['PNRRMK'];
		}
		elseif($this->hasStructByName('INTRM')) {
			$this->tree['INTRM'] = $matches['INTRM'];
		}

		if($this->hasStructByName('XLINEASS')) {
			$this->tree['XLINEASS'] = $matches['XLINEASS'];

			$struct = $this->getStructByName('XLINEASS');
			if($matches['XLINEASS'] && ($v = $this->parseFromStructure_v2_generalAssoc($struct, $this->tree['XLINEASS'], 0, []))){
				$this->tree[$struct['name']] = $v['value'];
			}
		}

		if($this->hasStructByName('SEGASS')) {
			$this->tree['SEGASS'] = $matches['SEGASS'];

			$struct = $this->getStructByName('SEGASS');
			if($matches['SEGASS'] && ($v = $this->parseFromStructure_v2_generalAssoc($struct, $this->tree['SEGASS'], 0, []))){
				$this->tree[$struct['name']] = $v['value'];
			}
		}

		if($this->hasStructByName('PSGASS')) {
			$this->tree['PSGASS'] = $matches['PSGASS'];

			$struct = $this->getStructByName('PSGASS');
			if($matches['PSGASS'] && ($v = $this->parseFromStructure_v2_generalAssoc($struct, $this->tree['PSGASS'], 0, []))){
				$this->tree[$struct['name']] = $v['value'];
			}
		}

		$this->postParse();
		return $this;
	}
}
