<?php

/**
 * Copyright (C) 2010-2024 Combodo SAS
 *
 * This file is part of iTop.
 *
 *  iTop is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * iTop is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with iTop. If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace Combodo\iTop\Test\UnitTest\Application\Search;

use Combodo\iTop\Application\Search\SearchForm;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use DBObjectSearch;
use Exception;

/**
 * @group itopRequestMgmt
 */
class SearchFormTest extends ItopDataTestCase
{
	public const CREATE_TEST_ORG = false;

	/**
	 * @dataProvider GetFieldsProvider
	 * @throws \OQLException
	 * @throws \CoreException
	 */
	public function testGetFields($sOQL)
	{
		$oSearchForm = new SearchForm();
		$oSearch = \DBSearch::FromOQL($sOQL);
		$aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch));
		$this->debug($sOQL);
		$this->debug(json_encode($aFields, JSON_PRETTY_PRINT));
		$this->assertTrue(count($aFields['zlist']) > 0);
		$this->assertTrue(count($aFields['others']) > 0);
	}

	public function GetFieldsProvider()
	{
		return [
			["SELECT Contact"],
			["SELECT Contact AS C WHERE C.status = 'active'"],
			["SELECT Person"],
			[
				"SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'",
			],
		];
	}

	/**
	 * @dataProvider GetCriterionProvider
	 *
	 * @param $sOQL
	 * @param $iOrCount
	 *
	 * @throws \CoreException
	 * @throws \MissingQueryArgument
	 */
	public function testGetCriterion($sOQL, $iOrCount)
	{
		$oSearchForm = new SearchForm();
		try {
			$oSearch = \DBSearch::FromOQL($sOQL);
			$aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch));
			/** @var DBObjectSearch $oSearch */
			$aCriterion = $oSearchForm->GetCriterion($oSearch, $aFields);
		} catch (\OQLException $e) {
			$this->assertTrue(false);

			return;
		}
		$aRes = ['base_oql' => $sOQL, 'criterion' => $aCriterion];
		$this->debug(json_encode($aRes));
		$this->debug($sOQL);
		$this->debug(json_encode($aCriterion, JSON_PRETTY_PRINT));
		$this->assertCount($iOrCount, $aCriterion['or']);
	}

	public function GetCriterionProvider()
	{
		return [
			['OQL' => "SELECT Contact", 1],
			['OQL' => "SELECT Contact WHERE status = 'active'", 1],
			['OQL' => "SELECT Contact AS C WHERE C.status = 'active'", 1],
			['OQL' => "SELECT Contact WHERE status = 'active' AND name LIKE 'toto%'", 1],
			['OQL' => "SELECT Contact WHERE status = 'active' AND org_id = 3", 1],
			['OQL' => "SELECT Contact WHERE status IN ('active', 'inactive')", 1],
			['OQL' => "SELECT Contact WHERE status NOT IN ('active')", 1],
			['OQL' => "SELECT Contact WHERE status NOT IN ('active', 'inactive')", 1],
			['OQL' => "SELECT Contact WHERE status = 'active' OR name LIKE 'toto%'", 2],
			['OQL' => "SELECT UserRequest WHERE DATE_SUB(NOW(), INTERVAL 14 DAY) < start_date", 1],
			['OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND '2018-01-01 00:00:00' >= start_date", 1],
			['OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND status = 'active' AND org_id = 3 AND '2018-01-01 00:00:00' >= start_date", 1],
			['OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 00:00:00' >= start_date", 1],
			['OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 01:00:00' > start_date", 1],
			['OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-02 00:00:00' > start_date", 1],
			[
				'OQL' => "SELECT FunctionalCI WHERE ((business_criticity IN ('high', 'medium')) OR ISNULL(business_criticity)) AND 1",
				1,
			],

		];
	}
}
