<?php

namespace App\ImportEmailBookings;

abstract class PopulateImportedOrderAbstract
{

	/**
	 * The parser object - this is used to load all info that is parsed from the email.
	 * @var ParserAbstract
	 */
	protected \App\ImportEmailBookings\ParserAbstract $parser;

	/**
	 * The external system code as it will be filled in the imported order.
	 * @var string
	 */
	protected string $externalSystemCode;

	/**
	 * Indicates if the current email must be skipped (eg. duplicates).
	 * @var ?string
	 */
	protected ?string $skipReason = null;

	/**
	 * Associates the parser object to be later used in populate().
	 * It is recommended that you overload this method, so the correct (specific) class type is forced.
	 * @param \App\ImportEmailBookings\ParserAbstract $parser
	 */
	public function __construct(\App\ImportEmailBookings\ParserAbstract $parser)
	{
		$this->parser = $parser;
	}


	/**
	 * Populates the provided imported order with details loaded from the parser object.
	 * @param \App\ImportedOrder\Order $importedOrder
	 */
	public function execute(\App\ImportedOrder\Order $importedOrder) :void
	{

		// check that the system code is defined in the concrete class
		if (!isset($this->externalSystemCode) or !strlen($this->externalSystemCode)) {
			throw new \Exception('The external system code is not defined for class ' . get_called_class() );
		}

		$this->checkParsedData();

		// populate only if we don't skip the current email
		if (!$this->skipReason) {
			$this->populateImportedOrderFields($importedOrder);
		}

	}


	/**
	 * Checks the data provided by the parser.
	 */
	abstract protected function checkParsedData() :void ;


	/**
	 * The actual population of the imported order object.
	 * @param \App\ImportedOrder\Order $importedOrder
	 */
	abstract protected function populateImportedOrderFields(\App\ImportedOrder\Order $importedOrder) :void ;


	/**
	 * Indicates the reason why the email is skipped.
	 * @return ?string
	 */
	public function getSkipReason(): ?string
	{
		return $this->skipReason;
	}

}

