<?php

namespace App\Classes\File;

use Illuminate\Support\Collection;

/**
 * A file we are sending or receiving
 *
 * For sending, we have sub types of Mail (Netmail/Echomail) and Files (File & TIC)
 * When sending, we can queue up a list of items, and mark one active (the one being sent) at a time.
 *
 * + Netmail/Echomail/TIC
 *   + name is dynamically calculated, based on timew() of the youngest item in the mail bundle
 *   + size is dynamically calculated based on the size of the bundle
 *   + mtime is dynamically calculated, based on the age of the youngest item
 *   + sendas (nameas) is name + [.pkt|.tic]
 *
 *   = Need to know the DB ID for the items being sent, so as to mark them sent
 *
 * + Files
 *   + name is the full path file name
 *   + size is the file size
 *   + mtime is the file mtime
 *   + sendas (nameas) is filename only
 *
 * For receiving, we just received files, and based on its name, we determine if it is a mail/file/tic or request
 * When receiving, we receive one file at a time, and our list has the list of files we've received
 *
 *   + name our name (including path) with the address ID prefixed of the sender
 *   + size is advised to us by the remote
 *   + mtime is advised to us by the remote
 *   + receiveas (nameas) advised to us by the remote
 *
 * @property string $name The (full path) name of the file we are sending or receiving
 * @property string $nameas The name as we communicate with the remote
 * @property int $mtime The date/time timestamp of the item we are sending or receiving
 * @property int $pos Our counter of where we have read to when sending
 * @property int $size The size of the item we are sending or receiving
 */
abstract class Base
{
	private const LOGKEY = 'I--';

	// @todo MAX_COMPSIZE hasnt been implemented in RECEIVE OR SEND
	/** @var int max size of file to use compression */
	protected const MAX_COMPSIZE	= 0x1fff;

	// 4 BITS of type
	protected const IS_FILE			= (1<<0);
	public const IS_PKT			= (1<<1);
	protected const IS_ARC			= (1<<2);
	protected const IS_REQ			= (1<<3);
	protected const IS_TIC			= (1<<4);

	/** Current read/write pointer */
	protected int $pos;

	/** File descriptor - for receiving this is the file resource, for sending, this is a string of the data to send */
	protected mixed $f;

	/** @var int Type of Item - first 8 bits are the type of item, the last 8 bits are dependent on the send/receive T_* values */
	protected int $ftype;

	/** @var Collection The list of items we are sending */
	protected Collection $list;

	/** @var int|null The item in the list that we are sending/receiving */
	protected ?int $index = NULL;

	/** @var bool Item has been sent or received */
	protected bool $complete = FALSE;

	/** Time we started sending/receiving */
	protected int $start;

	protected function isType(int $type): bool
	{
		return ($this->ftype&0xff) & $type;
	}

	public function whatType(): int
	{
		static $ext = ['su','mo','tu','we','th','fr','sa','req'];

		$x = strrchr($this->full_name,'.');

		if (! $x || (strlen(substr($x,1)) != 3))
			return self::IS_FILE;

		if (strcasecmp(substr($x,1),'pkt') === 0)
			return self::IS_PKT;

		if (strcasecmp(substr($x,1),'req') === 0)
			return self::IS_REQ;

		if (strcasecmp(substr($x,1),'tic') === 0)
			return self::IS_TIC;

		for ($i=0;$i<count($ext);$i++)
			if (! strncasecmp($x,'.'.$ext[$i],strlen($ext[$i]))
				&& (preg_match('/^[0-9a-z]/',strtolower(substr($x,3,1)))))
				return self::IS_ARC;

		return self::IS_FILE;
	}
}