<?php

namespace Modules\RemoteData\EntityManagementWs\Model\Entity;


abstract class SearchAbstract extends GeneralAbstract
{

	protected $forcedRequestAttributes = ['searchString', 'searchMode', 'offset', 'limit', 'columnOrder', 'directionOrder'];


	/**
	 * Checks if the request details are ok for this search.
	 * @throws \Modules\RemoteData\EntityManagementWs\Model\RuntimeException
	 */
	protected function checkRequestData() :void
	{

		// searchString
		if (mb_strlen($this->request->searchString) < 2) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The `searchString` must have at least 2 characters.', 'SearchStringLength');
		}

		// search mode
		if ($this->request->searchMode and !in_array($this->request->searchMode, ['contains', 'starts'])) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The `searchMode` must be set as `contains`, `starts`.', 'SearchModeInvalid');
		}

		// offset
		if ($this->request->offset and (!is_numeric($this->request->offset) or (Int)$this->request->offset!=$this->request->offset or $this->request->offset < 0)) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The `offset` must be integer and positive.', 'OffsetIntegerPositive');
		}

		// limit
		if (!$this->request->limit) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The `limit` is mandatory.', 'LimitMandatory');
		}

		if (!is_numeric($this->request->limit) or $this->request->limit<=0 or $this->request->limit>100 ) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The limit must be integer, positive and smaller than 100.', 'LimitIntegerPositive');
		}

		// directionOrder and columnOrder
		if (($this->request->directionOrder and !$this->request->columnOrder)) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('If you set the direction order you must also set the column order.', 'ColumnOrderNotSet');
		}

		// check direction order
		if ( $this->request->directionOrder and !in_array(strtolower($this->request->directionOrder), ['asc', 'desc']) ) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException('The direction order can only be set to `ASC` or `DESC`.', 'DirectionOrderInvalid');
		}

	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\RemoteData\EntityManagementWs\Model\Entity\GeneralAbstract::processRequest()
	 */
	protected function processRequest() :void
	{

		// copy all information search from request
		$this->response->searchString = $this->request->searchString;
		$this->response->searchMode =	$this->request->searchMode;
		$this->response->offset = 		$this->request->offset;
		$this->response->limit = 		$this->request->limit;
		$this->response->columnOrder = 	$this->request->columnOrder;
		$this->response->directionOrder=$this->request->directionOrder;

		// does the actual search
		$this->search();

	}

	/**
	 * Does the actual seearch.
	 */
	abstract protected function search() :void;


	/**
	 * Helper to indicate how the response is populated.
	 * @param array $listRecords
	 * @param int $totalResults
	 */
	protected function populateSearchResponse(array $listRecords, int $totalResults)
	{
		$this->response->listRecords = 	$listRecords;
		$this->response->totalResults = $totalResults;
	}

}

