<?php
namespace App\Galileo\FileParser;

class MIR extends \App\Utils\BaseParser\TextParser\FileParser\ParserForIndividualLines
{
	protected $extractRegexp = "/^(?P<rawData>T5.+[\s])/";

	/**
	 * The line structure
	 */
	protected $children = [
			[ 'key'=>'header',  'startsWith'=>'Header_Line1', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'line1',  'type'=>'Header_Line1', 'req' =>true ],
					[ 'key'=>'line2',  'type'=>'Header_Line2', 'req' =>true ],
					[ 'key'=>'line3',  'type'=>'Header_Line3', 'req' =>true ],
					[ 'key'=>'line4',  'type'=>'Header_Line4', 'req' =>true ],
					[ 'key'=>'line5',  'type'=>'Header_Line5', 'req' =>true ],
			]],

			[ 'key'=>'A00',        'startsWith'=>'Data_A00', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A00',              'type'=>'Data_A00', ],
					[ 'key'=>'A00continuation',  'type'=>'StringRaw', 'rep'=>[0, 64], ],
			]],

			[ 'key'=>'A01',        'startsWith'=>'Data_A01', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A01',  'type'=>'Data_A01', ],
			]],

			[ 'key'=>'A02',        'startsWith'=>'Data_A02', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A02',            'type'=>'Data_A02'],
					[ 'key'=>'A02Details',     'type'=>'Data_A02Details'],
			]],

			[ 'key'=>'A03',        'startsWith'=>'Data_A03', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A03',  'type'=>'Data_A03', ],
			]],

			[ 'key'=>'A04',        'startsWith'=>'Data_A04', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A04',  'type'=>'Data_A04', ],
			]],

			[ 'key'=>'A05',        'startsWith'=>'Data_A05', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A05',  'type'=>'Data_A05', ],
			]],

			[ 'key'=>'A07',        'startsWith'=>'Data_A07', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A07',           'type'=>'Data_A07'],
					[ 'key'=>'A07DetailsIT',  'type'=>'Data_A07DetailsIT', 'req'=>false,],
					[ 'key'=>'A07DetailsET',  'type'=>'Data_A07DetailsET', 'req'=>false,],
			]],

			[ 'key'=>'A08',        'startsWith'=>'Data_A08', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A08',  	'type'=>'Data_A08', ],
					[ 'key'=>'A08EF',  'type'=>'Data_A08EF', ],
			]],

			[ 'key'=>'A09',        'startsWith'=>'Data_A09', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A09',           'type'=>'Data_A09'],
					[ 'key'=>'A09Details01',  'type'=>'Data_A09Details01'],
					[ 'key'=>'A09Details02',  'type'=>'Data_A09Details02'],
					[ 'key'=>'A09Details03',  'type'=>'Data_A09Details03'],
					[ 'key'=>'A09Details04',  'type'=>'Data_A09Details04'],
					[ 'key'=>'A09Details05',  'type'=>'Data_A09Details05'],
			]],

			[ 'key'=>'A10',        'startsWith'=>'Data_A10', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A10',           'type'=>'Data_A10'],
					[ 'key'=>'A10Details01',  'type'=>'Data_A10Details01'],
					[ 'key'=>'A10Details02',  'type'=>'Data_A10Details02'],
					[ 'key'=>'A10Details03',  'type'=>'Data_A10Details03'],
					[ 'key'=>'A10Details04',  'type'=>'Data_A10Details04'],
					[ 'key'=>'A10Details05',  'type'=>'Data_A10Details05'],
					[ 'key'=>'A10Details06',  'type'=>'Data_A10Details06'],
					[ 'key'=>'A10Details07',  'type'=>'Data_A10Details07'],
			]],

			[ 'key'=>'A11',        'startsWith'=>'Data_A11', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'validRegexp'=> '/^A11(?P<all>.+)/', 'children'=>[
					[ 'key'=>'A11',  'type'=>'Data_A11', ],
			]],

			[ 'key'=>'A12',        'startsWith'=>'Data_A12', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'validRegexp'=> '/^A12(?P<all>.+)/', 'children'=>[
					[ 'key'=>'A12',  'type'=>'Data_A12', ],
			]],

			[ 'key'=>'A13',        'startsWith'=>'Data_A13', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'validRegexp'=> '/^A13(?P<all>.+)/', 'children'=>[
					[ 'key'=>'A13',  'type'=>'Data_A13', ],
			]],

			[ 'key'=>'A14',        'startsWith'=>'Data_A14', 'endsWith'=>'LineBlank', 'rep'=>[0, 999], 'validRegexp'=> '/^A14(?P<all>.+)/', 'children'=>[
					[ 'key'=>'A14',  'type'=>'Data_A14', ],
			]],

			[ 'key'=>'A15',        'startsWith'=>'Data_A15', 'endsWith'=>'LineBlank', 'rep'=>[0, 999], 'validRegexp'=> '/^A15(?P<all>.+)/', 'children'=>[
					[ 'key'=>'A15',  'type'=>'Data_A15', ],
			]],

			// A16 lines (services)

			// hotel
			[ 'key'=>'A16A',  'startsWith'=>'Data_A16A', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A16A',      'type'=>'Data_A16A'],
					[ 'key'=>'A16AOD',    'type'=>'Data_A16AOD'],
					[ 'key'=>'A16AO1',    'type'=>'Data_A16AO1'],
					[ 'key'=>'A16AO3',    'type'=>'Data_A16AO3'],
					[ 'key'=>'A16AFF',    'type'=>'Data_A16AFF', 'rep'=>[0, 64], ],
					[ 'key'=>'A16ACF',    'type'=>'Data_A16ACF'],
					[ 'key'=>'A16ADP',    'type'=>'Data_A16ADP', 'rep'=>[0, 64], ],
					[ 'key'=>'A16AW',     'type'=>'Data_A16AW'],
			]],
			[ 'key'=>'A167',  'startsWith'=>'Data_A167', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A167',      'type'=>'Data_A167'],
					[ 'key'=>'A167OD',    'type'=>'Data_A167OD'],
					[ 'key'=>'A167O1',    'type'=>'Data_A167O1'],
					[ 'key'=>'A167FF',    'type'=>'Data_A167FF', 'rep'=>[0, 64], ],
					[ 'key'=>'A167CF',    'type'=>'Data_A167CF'],
					[ 'key'=>'A167DP',    'type'=>'Data_A167DP', 'rep'=>[0, 64], ],
					[ 'key'=>'A167W',     'type'=>'Data_A167W'],
					[ 'key'=>'A167RM',    'type'=>'Data_A167RM'],
			]],


			// car
			// A168 & A168 are identical, but i had to define them twice for the parser
			[ 'key'=>'A16B',  'startsWith'=>'Data_A16B', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A16B',      'type'=>'Data_A16B'],
					[ 'key'=>'A16BOD',    'type'=>'Data_A16BOD'],
					[ 'key'=>'A16BO1',    'type'=>'Data_A16BO1'],
					[ 'key'=>'A16BFF',    'type'=>'Data_A16BFF', 'rep'=>[0, 64], ],
					[ 'key'=>'A16BCF',    'type'=>'Data_A16BCF'],
					[ 'key'=>'A16BDP',    'type'=>'Data_A16BDP', 'rep'=>[0, 64], ],
					[ 'key'=>'A16BW',     'type'=>'Data_A16BW'],
					[ 'key'=>'A16BVC',    'type'=>'Data_A16BVC'],
					[ 'key'=>'A16BCI',    'type'=>'Data_A16BCI'],
			]],
			[ 'key'=>'A168',  'startsWith'=>'Data_A168', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A168',      'type'=>'Data_A168'],
					[ 'key'=>'A168OD',    'type'=>'Data_A16BOD'],
					[ 'key'=>'A168O1',    'type'=>'Data_A16BO1'],
					[ 'key'=>'A168FF',    'type'=>'Data_A16BFF', 'rep'=>[0, 64], ],
					[ 'key'=>'A168CF',    'type'=>'Data_A16BCF'],
					[ 'key'=>'A168DP',    'type'=>'Data_A16BDP', 'rep'=>[0, 64], ],
					[ 'key'=>'A168W',     'type'=>'Data_A16BW'],
					[ 'key'=>'A168VC',    'type'=>'Data_A16BVC'],
					[ 'key'=>'A168CI',    'type'=>'Data_A16BCI'],
			]],

			// TUR?
			// A166 & A165 are identical, but i had to define them twice for the parser
			[ 'key'=>'A166',  'startsWith'=>'Data_A166', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A166',      'type'=>'Data_A166'],
					[ 'key'=>'A166OD',    'type'=>'Data_A166OD'],
					[ 'key'=>'A166FF',    'type'=>'Data_A166FF', 'rep'=>[0, 64], ],
					[ 'key'=>'A166CF',    'type'=>'Data_A166CF'],
					[ 'key'=>'A166DP',    'type'=>'Data_A166DP', 'rep'=>[0, 64], ],
					[ 'key'=>'A166W',     'type'=>'Data_A166W'],
					[ 'key'=>'A166UI',    'type'=>'Data_A166UI'],
			]],
			[ 'key'=>'A165',  'startsWith'=>'Data_A166', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A165',      'type'=>'Data_A166'],
					[ 'key'=>'A165OD',    'type'=>'Data_A166OD'],
					[ 'key'=>'A165FF',    'type'=>'Data_A166FF', 'rep'=>[0, 64], ],
					[ 'key'=>'A165CF',    'type'=>'Data_A166CF'],
					[ 'key'=>'A165DP',    'type'=>'Data_A166DP', 'rep'=>[0, 64], ],
					[ 'key'=>'A165W',     'type'=>'Data_A166W'],
					[ 'key'=>'A165UI',    'type'=>'Data_A166UI'],
			]],

			// Unassociated dues, paids and text
			[ 'key'=>'A16UZ',        'startsWith'=>'Data_A16UZ', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A16UZ',    'type'=>'Data_A16UZ', ],
			]],

			// SVC optional services
			[ 'key'=>'A169',  'startsWith'=>'Data_A169', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A169',     'type'=>'Data_A169'],
					[ 'key'=>'A169FX',   'type'=>'Data_A169FX'],
			]],
			/////////////////////////////

			[ 'key'=>'blank',    'type'=>'LineBlank',  'req'=>false, ],


			[ 'key'=>'A17',        'startsWith'=>'Data_A17', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A17',     'type'=>'Data_A17', ],
					[ 'key'=>'A17FT',   'type'=>'Data_A17FT', ],
					[ 'key'=>'A17FC',   'type'=>'Data_A17FC', ],
					[ 'key'=>'A17TR',   'type'=>'Data_A17TR', ],
					[ 'key'=>'A17PN',   'type'=>'Data_A17PN', ],
					[ 'key'=>'A17ST',   'type'=>'Data_A17ST', ],
					[ 'key'=>'A17PC',   'type'=>'Data_A17PC', ],
					[ 'key'=>'A17FO',   'type'=>'Data_A17FO', ],
					[ 'key'=>'A17AC',   'type'=>'Data_A17AC', ],
					[ 'key'=>'A17UD',   'type'=>'Data_A17UD', ],
					[ 'key'=>'A17CI',   'type'=>'Data_A17CI', ],
					[ 'key'=>'A17PP',   'type'=>'Data_A17PP', ],
					[ 'key'=>'A17PS',   'type'=>'Data_A17PS', ],
					[ 'key'=>'A17FF',   'type'=>'Data_A17FF', ],
					[ 'key'=>'A17DP',   'type'=>'Data_A17DP', ],
			]],

			[ 'key'=>'A19',        'startsWith'=>'Data_A19', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A19',     'type'=>'Data_A19', ],
					[ 'key'=>'A19ST',   'type'=>'Data_A19ST', ],
					[ 'key'=>'A19EB',   'type'=>'Data_A19EB', ],
					[ 'key'=>'A19R1',   'type'=>'Data_A19R1', ],
					[ 'key'=>'A19R1',   'type'=>'Data_A19R2', ],
					[ 'key'=>'A19R3',   'type'=>'Data_A19R3', ],
					[ 'key'=>'A19TN',   'type'=>'Data_A19TN', ],
					[ 'key'=>'A19ER',   'type'=>'Data_A19ER', ],
					[ 'key'=>'A19RI',   'type'=>'Data_A19RI', ],
			]],

			[ 'key'=>'A20',  'startsWith'=>'Data_A20', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A20',     'type'=>'Data_A20'],
					[ 'key'=>'A20FT',   'type'=>'Data_A20FT'],
			]],

			[ 'key'=>'A21',  'startsWith'=>'Data_A21', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A21',     'type'=>'Data_A21'],
			]],

			[ 'key'=>'A22',  'startsWith'=>'Data_A22', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A22',     'type'=>'Data_A22'],
			]],

			[ 'key'=>'A23',  'startsWith'=>'Data_A23', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A23',     'type'=>'Data_A23'],
					[ 'key'=>'A23TI',   'type'=>'Data_A23TI'],
					[ 'key'=>'A23OD',   'type'=>'Data_A23OD'],
					[ 'key'=>'A23BF',   'type'=>'Data_A23BF'],
					[ 'key'=>'A23XF',   'type'=>'Data_A23XF'],
					[ 'key'=>'A23IT',   'type'=>'Data_A23IT'],
					[ 'key'=>'A23AU',   'type'=>'Data_A23AU'],
					[ 'key'=>'A23CR',   'type'=>'Data_A23CR'],
					[ 'key'=>'A23PF',   'type'=>'Data_A23PF'],
					[ 'key'=>'A23RA',   'type'=>'Data_A23RA'],
					[ 'key'=>'A23FP1',  'type'=>'Data_A23FP1'],
					[ 'key'=>'A23FP2',  'type'=>'Data_A23FP2'],
					[ 'key'=>'A23FP3',  'type'=>'Data_A23FP3'],
					[ 'key'=>'A23MF',   'type'=>'Data_A23MF'],
					[ 'key'=>'A23BFL',  'type'=>'Data_A23BFL'],
					[ 'key'=>'A23RAL',  'type'=>'Data_A23RAL'],
					[ 'key'=>'A23FP1L', 'type'=>'Data_A23FP1L'],
					[ 'key'=>'A23FP2L', 'type'=>'Data_A23FP2L'],
					[ 'key'=>'A23FP3L', 'type'=>'Data_A23FP3L'],
					[ 'key'=>'A23ERT',  'type'=>'Data_A23ERT'],
					[ 'key'=>'A23WC',   'type'=>'Data_ignored', 'validRegexp'=> '/^WC:(?P<all>.+)/'],
			]],

			[ 'key'=>'A24',  'startsWith'=>'Data_A24', 'endsWith'=>'LineBlank',    'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A24',         'type'=>'Data_A24'],
					[ 'key'=>'A24Line02',   'type'=>'Data_A24Line02'],
					[ 'key'=>'A24Line03',   'type'=>'Data_A24Line03'],
					[ 'key'=>'A24Line04',   'type'=>'Data_A24Line04'],
					[ 'key'=>'A24Line05',   'type'=>'Data_A24Line05'],
					[ 'key'=>'A24Vat',      'type'=>'Data_A24Vat'],
			]],

			[ 'key'=>'A26',  'startsWith'=>'Data_A26', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A26',         'type'=>'Data_A26'],
			]],

			[ 'key'=>'A27',  'startsWith'=>'Data_A27', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A27',         'type'=>'Data_A27'],
					[ 'key'=>'A27OB',       'type'=>'Data_A27OB'],
			]],

			[ 'key'=>'A28',  'startsWith'=>'Data_A28', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
					[ 'key'=>'A28',         'type'=>'Data_A28'],
					[ 'key'=>'A28Taxes',    'type'=>'Data_A28Taxes'],
					[ 'key'=>'A28IT',       'type'=>'Data_A28IT'],
					[ 'key'=>'A28ET',       'type'=>'Data_A28ET'],
			]],

			[ 'key'=>'EMD',  'startsWith'=>'Data_A29', 'endsWith'=>'LineBlank',  'rep'=>[0, 64], 'children'=>[
				[ 'key'=>'A29',  'startsWith'=>'Data_A29', 'endsWith'=>'LineBlank', 'children'=>[
						[ 'key'=>'A29',         'type'=>'Data_A29'],
						[ 'key'=>'A29Details',  'type'=>'Data_A29Details'],
				]],

				[ 'key'=>'A30',  'startsWith'=>'Data_A30', 'endsWith'=>'LineBlank', 'rep'=>[0, 64], 'children'=>[
						[ 'key'=>'A30',         'type'=>'Data_A30'],
						[ 'key'=>'A30Details',  'type'=>'Data_A30Details'],
				]],

				[ 'key'=>'A10',        'startsWith'=>'Data_A10', 'endsWith'=>'LineBlank', 'children'=>[
					[ 'key'=>'A10',           'type'=>'Data_A10'],
					[ 'key'=>'A10Details01',  'type'=>'Data_A10Details01'],
					[ 'key'=>'A10Details02',  'type'=>'Data_A10Details02'],
					[ 'key'=>'A10Details03',  'type'=>'Data_A10Details03'],
					[ 'key'=>'A10Details04',  'type'=>'Data_A10Details04'],
					[ 'key'=>'A10Details05',  'type'=>'Data_A10Details05'],
					[ 'key'=>'A10Details06',  'type'=>'Data_A10Details06'],
					[ 'key'=>'A10Details07',  'type'=>'Data_A10Details07'],
				]],
			]],

			[ 'key'=>'blank',    'type'=>'LineBlank',  'req'=>false, ],
			[ 'key'=>'blank',    'type'=>'LineBlank',  'req'=>false, ],
	];

	/**
	 * (non-PHPdoc)
	 * @see \App\Utils\BaseParser\TextParser\BlockAbstract::createObject()
	 */
	public function createObject($type, $options, $self)
	{
		$options['req'] = true;
		$obj = null;

		$class = sprintf("\App\Galileo\LineParser\Types\%s", $type);
		if (class_exists($class)) {
			$obj = new $class($options, $self);
		}

		if (!$obj) {
			$obj = parent::createObject($type, $options, $self);
		}

		$obj->setHelper($this->lineHelper);
		return $obj;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Utils\BaseParser\TextParser\BlockAbstract::postExtract()
	 */
	protected function postExtract(\App\Utils\BaseParser\TextParser\ExtractedBlock $ret)
	{
		// perform some post-parsing file validations
		if ($ret->extractedData['A02'] && $ret->extractedData['header']['line5']['T50PGN'] && $ret->extractedData['header']['line5']['T50PGN'] != count($ret->extractedData['A02'])) {
			$this->getMessagesCollector()->addWarning(sprintf("Invalid file. T50PGN doesn't match number of A02 lines, (%d vs %d)", $ret->extractedData['header']['line5']['T50PGN'], count($ret->extractedData['A02'])));
		}

		if ($ret->extractedData['A07'] && $ret->extractedData['header']['line5']['T50FBN'] && $ret->extractedData['header']['line5']['T50FBN'] != count($ret->extractedData['A07'])) {
			throw new \App\Utils\BaseParser\TextParser\FileParser\Exception\General(sprintf("Invalid file. T50FBN doesn't match number of A07 lines, (%d vs %d)", $ret->extractedData['header']['line5']['T50FBN'], count($ret->extractedData['A07'])));
		}

		if ($ret->extractedData['header']['line1']['T50SPC_']!='GALILEO') {
			throw new \App\Utils\BaseParser\TextParser\FileParser\Exception\General(sprintf("Invalid file. This is not an Galileo file"));
		}

		if ($ret->extractedData['A07']) {
			$T50CUR = $ret->extractedData['header']['line3']['T50CUR'];
			$totalEquivalentPrice = 0.0;
			$canValidate = true;

			foreach ($ret->extractedData['A02'] as $a02) {
				$a07 = null;
				foreach ($ret->extractedData['A07'] as $v) {
					if ($a02['A02']['A02FIN']==$v['A07']['A07FSI']) {
						$a07 = $v;
						break;
					}
				}

				if ($a07) {
					if ($T50CUR==$a07['A07']['A07CRE']) {
						$totalEquivalentPrice+= $a07['A07']['A07EQV'];
					}
					elseif ($T50CUR==$a07['A07']['A07CRB']) {
						$totalEquivalentPrice+= $a07['A07']['A07TBF'];
					}
					else {
						$this->getMessagesCollector()->addWarning(sprintf("A07 contains lines with a different currency than the one specified in T50CUR. Cannot validate the total price for this file"));
						$canValidate = false;
					}
				}
				else {
					$this->getMessagesCollector()->addWarning(sprintf("A02 contains a passenger without a price line(A07) associated. Cannot validate prices in this file"));
					$canValidate = false;
				}
			}

			if ($canValidate && $ret->extractedData['header']['line3']['T50FAR_'] != $totalEquivalentPrice) {
				$this->getMessagesCollector()->addWarning(sprintf("Possible invalid file. T50FAR doesn't match the total amount of all passengers in this file(%.2f vs %.2f %s)", $ret->extractedData['header']['line3']['T50FAR_'], $totalEquivalentPrice, $T50CUR));
			}
		}

		if ($ret->extractedData['A09']) {
			foreach ($ret->extractedData['A09'] as $keyGroup => $A09group) {
				$A09L51 = '';
				foreach ($A09group as $A09Line) {
					$A09L51.= $A09Line['A09L51'];
				}

				if ($A09L51 && strpos($A09L51, "XT") !== FALSE) {
					$ret->extractedData['A09'][$keyGroup]['A09']['A09L51__'] = $A09L51;
					$ret->extractedData['A09'][$keyGroup]['A09']['A09L51_'] = [
						'unknownFormat' => true,
					];

					if (!$A09Line['A09TY5']) {
						try {
							$fareCalculationExtractorObject = \App\Utils\BaseParser\Utils\FareCalculationExtractor::getInstance();
							$ret->extractedData['A09'][$keyGroup]['A09']['A09L51_'] = $fareCalculationExtractorObject->extract($A09L51);
						}
						catch (\App\Utils\BaseParser\TextParser\Exception\LineParser $ex) {
							$this->getMessagesCollector()->addWarning(sprintf("%s: %s", $ex->getMessage(), $A09L51));
						}
					}
				}
			}
		}

		$shouldParseNDC = false;
		$shouldParseLCC = false;
		if ($ret->extractedData['A14']) {
			foreach ($ret->extractedData['A14'] as $A14) {
				if (preg_match('/#TAS[0-9]{2}#REF.+\/NDC$/', $A14['A14']['A14DTA'])) {
					$shouldParseNDC = true;
					break;
				}
				elseif (preg_match('/#TAS[0-9]{2}#REF.+$/', $A14['A14']['A14DTA'])) {
					$shouldParseLCC = true;
					break;
				}
			}
		}

		if ($shouldParseNDC) {
			$ret->extractedData['A14_NDC'] = [];
			$NDCContent = [];
			foreach ($ret->extractedData['A14'] as $A14) {
				if (preg_match('/#TAS[0-9]{2}#/', $A14['A14']['A14DTA'])) {
					$NDCContent[] = $A14['A14']['A14DTA'];
				}
			}

			try {
				$NDCParser = new \App\Galileo\NDCFileParser\NDC();
				$NDCParser->setRawData(implode("\n", $NDCContent));
				$NDCParser->extract();

				$ret->extractedData['A14_NDC'] = $NDCParser->getExtractedData();
			}
			catch (\App\Utils\BaseParser\TextParser\FileParser\Exception\UnprocessedLinesRemaining $ex) {
				// $this->getMessagesCollector()->addWarning(sprintf("NDC file parsing failed: %s", $ex->getMessage()));
				throw new \App\Utils\BaseParser\TextParser\FileParser\Exception\UnprocessedLinesRemaining("<pre>Error while parsing NDC content. {$ex->getMessage()}</pre>");
			}
		}


		if ($shouldParseLCC) {
			$ret->extractedData['A14_LCC'] = [];
			$LCCContent = [];
			foreach ($ret->extractedData['A14'] as $A14) {
				if (preg_match('/#TAS[0-9]{2}#/', $A14['A14']['A14DTA'])) {
					$LCCContent[] = $A14['A14']['A14DTA'];
				}
			}

			try {
				$LCCParser = new \App\Galileo\NDCFileParser\LCC();
				$LCCParser->setRawData(implode("\n", $LCCContent));
				$LCCParser->extract();

				$ret->extractedData['A14_LCC'] = $LCCParser->getExtractedData();
			}
			catch (\App\Utils\BaseParser\TextParser\FileParser\Exception\UnprocessedLinesRemaining $ex) {
				throw new \App\Utils\BaseParser\TextParser\FileParser\Exception\UnprocessedLinesRemaining("<pre>Error while parsing LCC content. {$ex->getMessage()}</pre>");
			}
		}

		return parent::postExtract($ret);
	}

	/**
	 * Get the unique file id
	 * @return string
	 */
	public function getFileId()
	{
		$ID = sprintf("%s%05d%s",
			\Engine\DateTime::createFromIsoDate($this->extractedData['header']['line1']['T50CRE']['T50DTE'])->format("Ymd"),
			$this->extractedData['header']['line1']['T50SEQ'],
			$this->extractedData['header']['line2']['T50RCL']
		);
		return $ID;
	}

	/**
	 * Destroy CC information from the current file
	 * Is can remove by doing str_replace over each encountered line
	 *
	 * @param array $regexpReplacements
	 * @return array
	 */
	public function destroyCCInformationAndWriteInto($filePath, ?\App\Utils\BaseParser\TextCleaner\TextCleaner $textCleaner = null)
	{
		$CFG = \Engine\Loader_Cfg::getInstance()->getGlobal();
		if (!$CFG['pciDss']['compliant']) {
			return [];
		}

		$hitLines = [];

		$contents = $this->rawData;
		$parsedStructure = $this->getExtractedData();

		$textCleaner = ($textCleaner?:new \App\Utils\BaseParser\TextCleaner\TextCleaner());

		// remove from associated I lines
		if ($parsedStructure['A11']) {
			foreach ($parsedStructure['A11'] as $A11) {
				if ($A11['A11']['A11TYP']=='CC' && $A11['A11']['A11CCC'] && $A11['A11']['A11CCN']) {
					$textCleaner->appendRule(new \App\Utils\BaseParser\TextCleaner\RuleLineRegexpAndTextReplacement(
						sprintf("^A11.*%s%s", preg_quote($A11['A11']['A11CCC'], '/'), preg_quote($A11['A11']['A11CCN'], '/')),
						sprintf("%s%s", $A11['A11']['A11CCC'], $A11['A11']['A11CCN']),
						sprintf("%s%s", $A11['A11']['A11CCC'], \App\Utils\CreditCard\NumberDetails::create((string)$A11['A11']['A11CCN'])->getMaskedNumber())
					));
				}
			}
		}

		if ($parsedStructure['A23']) {
			if ($parsedStructure['A23']['A23FP1']) {
				if ($parsedStructure['A23']['A23FP1']['A23CC1'] && $parsedStructure['A23']['A23FP1']['A23FP1']) {
					$textCleaner->appendRule(new \App\Utils\BaseParser\TextCleaner\RuleLineRegexpAndTextReplacement(
						sprintf("^FP1:.*%s%s", preg_quote($parsedStructure['A23']['A23FP1']['A23CC1'], '/'), preg_quote($parsedStructure['A23']['A23FP1']['A23FP1'], '/')),
						sprintf("%s%s", $parsedStructure['A23']['A23FP1']['A23CC1'], $parsedStructure['A23']['A23FP1']['A23FP1']),
						sprintf("%s%s", $parsedStructure['A23']['A23FP1']['A23CC1'], \App\Utils\CreditCard\NumberDetails::create((string)$parsedStructure['A23']['A23FP1']['A23FP1'])->getMaskedNumber())
					));
				}
			}
		}

		if ($textCleaner->hasRules()) {
			$contentArr = explode("\n", $contents);
			$originalContentsArr = $contentArr;

			list($contentArr, , $hitLines) = $textCleaner->simplifyRules()->cleanupArrRaw($contentArr);

			// NOTE: we could make sure all regexps applied at least once. If not, then some CC's might have gotten skipped

			// write the file back to disk, if any differences were found. We might have just parsed a file that was already masked, so no real changes were done
			if ($contentArr!=$originalContentsArr) {
				\Engine\File::create($filePath, implode("\n", $contentArr));
			}
		}

		return array_keys($hitLines);
	}
}
