<?php

namespace App\Classes\FTN\Packet;

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

use App\Classes\FTN\Packet;
use App\Models\Setup;

/**
 * FTS-0001 http://ftsc.org/docs/fts-0001.016
 *
 * Commonly known as Type 2 packets
 * Supports 3D addresses
 */
final class FTS1 extends Packet
{
	protected const HEADER = [
		'onode'			=> [0x00,'v',2],	// Orig Node
		'dnode'			=> [0x02,'v',2],	// Dest Node
		'y'				=> [0x04,'v',2],	// Year
		'm'				=> [0x06,'v',2],	// Month
		'd'				=> [0x08,'v',2],	// Day
		'H'				=> [0x0a,'v',2],	// Hour
		'M'				=> [0x0c,'v',2],	// Minute
		'S'				=> [0x0e,'v',2],	// Second
		'baud'			=> [0x10,'v',2],	// Baud
		'type'			=> [0x12,'v',2],	// Packet Version (should be 2)
		'onet'			=> [0x14,'v',2],	// Orig Net
		'dnet'			=> [0x16,'v',2],	// Dest Net
		'prodcode'		=> [0x18,'C',1],	// Product Code
		'serial'		=> [0x19,'C',1],	// Serial Number
		'password'		=> [0x1a,'a8',8],	// Packet Password
		'ozone'			=> [0x22,'v',2],	// Orig Zone
		'dzone'			=> [0x24,'v',2],	// Dest Zone
		'reserved'		=> [0x26,'a20',20],	// Reserved
	];

	public const TYPE = '2';

	public function __get($key)
	{
		switch ($key) {
			case 'product':
				return Arr::get($this->header,'prodcode');

			case 'software_ver':
				return 'N/A';

			default:
				return parent::__get($key);
		}
	}

	/**
	 * Create our message packet header
	 */
	protected function header(Collection $msgs): string
	{
		$oldest = $this->messages->sortBy('datetime')->last();

		return pack(collect(self::HEADER)->pluck(1)->join(''),
			$this->fftn_p->node_id,				// Orig Node
			$this->tftn_p->node_id,						// Dest Node
			$oldest->datetime->format('Y'),				// Year
			$oldest->datetime->format('m')-1,			// Month
			$oldest->datetime->format('d'),				// Day
			$oldest->datetime->format('H'),				// Hour
			$oldest->datetime->format('i'),				// Minute
			$oldest->datetime->format('s'),				// Second
			0,											// Baud
			2,											// Packet Version (should be 2)
			$this->fftn_p->host_id,						// Orig Net
			$this->tftn_p->host_id,						// Dest Net
			(Setup::PRODUCT_ID & 0xff),					// Product Code Lo
			Setup::PRODUCT_VERSION_MAJ,					// Product Version Major
			$this->pass_p ?: $this->tftn_p->pass_packet,		// Packet Password
			$this->fftn_p->zone->zone_id,				// Orig Zone
			$this->tftn_p->zone->zone_id,				// Dest Zone
			'',											// Reserved
		);
	}

	/**
	 * Determine if this is a fsc-0045 packet
	 *
	 * @param string $header
	 * @return bool
	 * @throws \Exception
	 */
	public static function is_type(string $header): bool
	{
		$head = unpack(self::unpackheader(self::HEADER),$header);

		return (
			(Arr::get($head,'type') === 2)
			&& (strlen(rtrim(Arr::get($head,'reserved'),"\x00")) === 0)
		);
	}
}