<?php
namespace App\Amadeus\FileParser;

class Line_S extends \App\Amadeus\FileParser\LineAbstract
{
	/**
	 * 4.107. S- Seat Number Data
	 * see page 283(325)
	 *
	 * In this pseudo EDIFACT segment no separators are used. The 'segment' will be terminated by a Carriage return
	 * Each ticketed air segment in the AIR is represented in the 'S' line and separated by a delimiter (;). Change of guage flights are separated by a delimiter (,).
	 */
	protected $structure = [
		['name'=> 'MSGTAG',     'val' => 'S-',    'type' => 'AN',   'req' => 'M',                                      'len' => 2,],                          // 1 : Message Tag (S-)
		['name'=> 'PSGNBR',                       'type' => 'N',    'req' => 'M',                                      'len' => 2,],                          // 2 : Passenger number in the PNR.
		['name' => 'SEATINFO',                    'type' =>'composite',                                                'rep_min' =>0,    'rep_max' =>99,      // 3 Seat Information. This is a composite element.
		 'childs' => [
		   ['name'=> 'fld',   				    'type' => 'AN',   'req' => 'M',],
// 		   Array( 'name'=> 'BRDPT',                     'type' => 'AN',                                                      'len_min' => 3,   'len_max' => 5,),    // 4 : Boardpoint. Exists only if seat element is for change of guage.
// 		   Array( 'name'=> 'DELIM1',   'val' => '.',    'type' => 'AN',                                                      'len' => 1,),                          // 5 : Delimiter (Constant value of '.')
// 		   Array( 'name'=> 'BOARDL',                    'type' => 'AN',                  'requires' => Array( 'DELIM1'),     ),                                                                           // 6 : Expanded Boardpoint name.
// 		   Array( 'name'=> 'DELIM2',   'val' => '.',    'type' => 'AN',                  'requires' => Array( 'DELIM1'),     'len' => 1,),                          // 7 : Delimiter (Constant value of '.')
// 		   Array( 'name'=> 'OFFPT',                     'type' => 'AN',                  'requires' => Array( 'DELIM2'),     'len_min' => 3,   'len_max' => 5,),    // 8 : Offpoint.
// 		   Array( 'name'=> 'DELIM3',   'val' => '.',    'type' => 'AN',                  'requires' => Array( 'DELIM2'),     'len' => 1,),                          // 9 : Delimiter (Constant value of '.')
// 		   Array( 'name'=> 'OFFL',                      'type' => 'AN',                  'requires' => Array( 'DELIM3'),     ),                                                                           // 10 : Expanded offpoint name.
// 		   Array( 'name'=> 'DELIM4',   'val' => '/',    'type' => 'AN',   'req' => 'M',  'requires' => Array( 'DELIM3'),     'len' => 1,),                          // 11 : Delimiter (Constant value of '/')
// 		   Array( 'name'=> 'SEATST',                    'type' => 'AN',                  'requires' => Array( 'DELIM4'),     'len' => 1,),                          // 12 : Seat Status (R=reserved, A=Reserved and Boarding Pass issued, S=Reserved only, Boarding Pass issuance restricted, B=Reserved, Issue Boarding Pass (ATB), and P=Unconfirmed seat preference (ATB)).
// 		   Array( 'name'=> 'SEATNBR',                   'type' => 'AN',                  'requires' => Array( 'DELIM4'),     'len_min' => 3,   'len_max' => 10,),   // 13 : Seat Number/Rail Carriage
// 		   Array( 'name'=> 'DELIM5',   'val' => '+',    'type' => 'AN',                  'requires' => Array( 'DELIM4'),     'len' => 1,),                          // 14 : Delimiter (Constant value of '+')On existence of Rail Seat
// 		   Array( 'name'=> 'RAILSEAT',                  'type' => 'AN',                  'requires' => Array( 'DELIM5'),     'len_min' => 1,   'len_max' => 10,),   // 15 : Seat Number when Rail Carriage Identifiable
// 		   Array( 'name'=> 'DELIM6',   'val' => '.',    'type' => 'AN',                  'requires' => Array( 'DELIM5'),     'len' => 1,),                          // 16 : Delimiter (Constant value of '.')
// 		   Array( 'name'=> 'SMOKE',                     'type' => 'AN',                  'requires' => Array( 'DELIM6'),     'len' => 1,),                          // 17 : Smoking/Non smoking Identifier (S) or (N)
// 		   Array( 'name'=> 'DELIM7',   'val' => ',',    'type' => 'AN',                  'requires' => Array( 'SMOKE'),      'len' => 1,),                          // 18 : Delimiter (Constant value of ','). Exists if will be followed by seat data for a change of guage. Max 5 seat data per flight.
		   ['name'=> 'DELIM',   'val' => ';',     'type' => 'AN',   'req' => 'M',                                      'len' => 1,],                          // 19 : Delimiter (Constant value of ';'). Shall NOT exist if would be followed by seat data for a change of guage. No delimiter follows the last seat data.
		 ]],                                                                                                                                                         // 20
	];

	protected $SEATST = [
		'R' => 'Reserved',
		'A' => 'Reserved and Boarding Pass issued',
		'S' => 'Reserved only, Boarding Pass issuance restricted',
		'B' => 'Reserved, Issue Boarding Pass (ATB)',
		'P' => 'Unconfirmed seat preference (ATB)',
	];

	/**
	 * Extract seat info from the input data, because the SEATINFO structure is too flexible to be able to format it by using the parser rules above, we have to do this manually
	 */
	protected function extractSeatInfo($seatInfo, $v)
	{
		// the seat structure may contain '/'.. so i cannot use explode

		// Ex: JFK.NEW YORK JFK.CDG.PARIS C DE GAULLE/R12A.S
		$m = [];
		preg_match("/^(?P<board>[^\/]*)\/(?P<seat>.*)$/i", $seatInfo, $m);
		$board = 	$m['board'];	// Ex: JFK.NEW YORK JFK.CDG.PARIS C DE GAULLE
		$seat = 	$m['seat'];		// Ex: R12A.S

		if($board){
			if(preg_match(
					"/^".
					"((?P<BRDPT>[^\.]*)\.)?".	// JFK.
					"((?P<BOARDL>[^\.]*)\.)?".	// NEW YORK JFK.
					"((?P<OFFPT>[^\.]*)\.)?".	// CDG.
					"((?P<OFFL>.*))?".			// PARIS C DE GAULLE
					"$/i", $board, $m)){
					$v['BRDPT'] = 	$m['BRDPT'];
					$v['BOARDL'] = 	$m['BOARDL'];
					$v['OFFPT'] = 	$m['OFFPT'];
					$v['OFFL'] = 	$m['OFFL'];
			}else{
				throw \App\Amadeus\FileParser\ParserException::internal("Unknown BOARD structure in the SEATINFO subtag, content '{$board}'");
			}
		}

		if($seat){
			if(preg_match(
					"/^".
					"((?P<SEATST>.{1}))?".			// R
					"((?P<SEATNBR>[^\+]*)\+)?".		// 12A.
					"((?P<RAILSEAT>[^\.]*)\.)?".
					"((?P<SMOKE>S|N|\s))?".			// S
					"$/i", $seat, $m)){

					$v['SEATST'] = 	$m['SEATST'];
					$v['SEATNBR'] = $m['SEATNBR'];
					$v['RAILSEAT'] =$m['RAILSEAT'];
					$v['SMOKE'] = 	trim($m['SMOKE']);

					$v['SEATST_'] = $this->SEATST[$v['SEATST']];
			}else{
				throw \App\Amadeus\FileParser\ParserException::internal("Unknown SEAT structure in the SEATINFO subtag, content '{$seat}'");
			}
		}

		return $v;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Amadeus\FileParser\LineAbstract::postParse()
	 */
	protected function postParse()
	{
		// call the parent first
		parent::postParse();

		if($this->tree['SEATINFO']){
			foreach($this->tree['SEATINFO'] as $k=>$v){
				if($v['fld']){
					$change_of_gaugesArr = explode(",", $v['fld']);

					// foreach change, record an element in the list
					foreach($change_of_gaugesArr as $gaugeIndex=>$c_o_g){
						$seat = $this->extractSeatInfo($c_o_g, []);
						if($gaugeIndex==0){
							$v = $seat;
						}else{
							$v['change_of_gauge'][] = $seat;
						}
					}

					$this->tree['SEATINFO'][$k] = $v;
				}
			}

			$this->tree['SEATINFO'] = self::rtrimArr($this->tree['SEATINFO']);
		}
	}
}
