<?php

namespace CirrusSearch\Tests\Maintenance;

use CirrusSearch\CirrusIntegrationTestCase;
use CirrusSearch\HashSearchConfig;
use CirrusSearch\Maintenance\SuggesterAnalysisConfigBuilder;

/**
 * @group CirrusSearch
 * @covers \CirrusSearch\Maintenance\SuggesterAnalysisConfigBuilder
 */
class SuggesterAnalysisConfigBuilderTest extends CirrusIntegrationTestCase {

	public static function provideLanguageAnalysis() {
		foreach ( CirrusIntegrationTestCase::findFixtures( 'languageAnalysisCompSuggest/*.config' ) as $testFile ) {
			$testName = substr( basename( $testFile ), 0, -7 );
			$extraConfig = CirrusIntegrationTestCase::loadFixture( $testFile );
			$langCode = $extraConfig['LangCode'] ?? $testName;
			$expectedFile = dirname( $testFile ) . "/$testName.expected";
			yield $testName => [ $expectedFile, $langCode, $extraConfig ];
		}
	}

	/**
	 * Test various language specific analysers against fixtures, to make
	 *  the results of generation obvious and tracked in git
	 *
	 * @dataProvider provideLanguageAnalysis
	 * @param mixed $expected
	 * @param string $langCode
	 * @param array $extraConfig
	 */
	public function testLanguageAnalysis( $expected, $langCode, array $extraConfig ) {
		$this->setTemporaryHook( 'CirrusSearchAnalysisConfig',
			static function () {
			}
		);
		$baseConfig = [
			'CirrusSearchSimilarityProfile' => 'default',
			'CirrusSearchCompletionPlainTokenizer' => 'whitespace'
		];
		$config = new HashSearchConfig( $extraConfig + $baseConfig );
		$plugins = [
			'analysis-stempel', 'analysis-kuromoji',
			'analysis-smartcn', 'analysis-hebrew',
			'analysis-ukrainian', 'analysis-stconvert',
			'extra-analysis-serbian', 'extra-analysis-slovak',
			'extra-analysis-esperanto', 'analysis-nori',
		];
		$builder = new SuggesterAnalysisConfigBuilder( $langCode, $plugins, $config );
		if ( !CirrusIntegrationTestCase::hasFixture( $expected ) ) {
			if ( self::canRebuildFixture() ) {
				CirrusIntegrationTestCase::saveFixture( $expected, $builder->buildConfig() );
				$this->markTestSkipped();
				return;
			} else {
				$this->fail( 'Missing fixture file ' . $expected );
			}
		} else {
			$expectedConfig = CirrusIntegrationTestCase::loadFixture( $expected );
			$this->assertEquals( $expectedConfig, $builder->buildConfig() );
		}
	}
}
