<?php
namespace App\Spotlight;

abstract class SourceAbstract
{

	/**
	 * The original search string.
	 * @var string
	 */
	protected $searchString;

	/**
	 * The cached words for the current search string.
	 * @var array
	 */
	protected $searchWords = [];

	/**
	 * The last search total records count (when running stolen source option searches)
	 * @var integer
	 */
	protected $lastSearchTotalCount = 0;

	/**
	 * @var \App\Utils\BaseParser\Utils\Extractor\SingleOptimized
	 */
	protected $extractor = null;

	public function __construct()
	{
		$this->extractor = new \App\Utils\BaseParser\Utils\Extractor\SingleOptimized();
	}

	/**
	 * Sets the search string and also stored the cached words.
	 * @param string $searchString
	 */
	public function setSearchString($searchString)
	{
		$this->searchString = $searchString;
		$this->searchWords = preg_split("/[\s]+/", $searchString);
	}

	/**
	 * Indicates if a label is correctly matched with the current search string.
	 * @param string $searchString
	 */
	protected function matchesSearchString($label)
	{

		if (!$this->searchWords) return false;

		foreach($this->searchWords as $word) {
			if (mb_stripos($label, $word)===false) {
				return false;
			}
		}

		return true;

	}

	/**
	 * Returns the records of the search.
	 * @param int $offset
	 * @param int $resultsPerPage
	 * @throws \Exception
	 * @return array
	 */
	public function getRecords($offset, $resultsPerPage)
	{
		$records = $this->determineRecords($offset, $resultsPerPage);
		foreach($records as $record) {
			if (!($record instanceof Record)) {
				throw new \Exception('The output of `'.__METHOD__.'` must be an array of `Record` class.');
			}
		}

		return $records;

	}

	/**
	 * Returns the  list of records.
	 * @return array
	 */
	abstract protected function determineRecords($offset, $resultsPerPage):array;


	/**
	 * Indicates if the current text may steal the focus of this entire search.
	 * @throws \Exception
	 */
	public function shouldStealFocus()
	{

		if ($this->searchString===null) {
			throw new \Exception('You must set the search string before calling '.__METHOD__);
		}

		return false;
	}

	/**
	 * Returns the total count of the last search.
	 * @return number
	 */
	public function getLastSearchTotalCount()
	{
		return $this->lastSearchTotalCount;
	}

}

