<?PHP
/**
 * Tests for the concordance checker.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Small;
use PHPUnit\Framework\Attributes\DataProvider;

/**
 * Tests for the concordance checker.
 */
#[small]
#[CoversClass(\ConcordanceChecker::class)]
final class ConcordanceCheckerTest extends PHPUnit\Framework\TestCase {
    /**
     * Tests for the concordance checker.
     *
     * @author Joshua Ramon Enslin <joshua@museum-digital.de>
     *
     * @return void
     */
    public function testValidConcordanceListsAreAcceptedInConstrutor():void {

        $files = MD_STD::scandir(__DIR__ . '/../dependencies/MDImporterConcordanceLists/src/');

        $this->expectNotToPerformAssertions();
        foreach ($files as $file) {
            if (!is_file($file)) continue;
            $className = pathinfo($file, PATHINFO_FILENAME);
            if (empty($className)) continue;
            if (in_array($className, ConcordanceChecker::DISABLED_CONCORDANCE_LISTS, true)) {
                continue;
            }
            new ConcordanceChecker($className);
        }

    }

    /**
     * Data provider for invalid concordance lists.
     *
     * @return array<string, array{0: non-empty-string}>
     */
    public static function invalid_concordance_list_class_provider():array {

        return [
            "Class that does not exist" => ["hjhifjaiojfaklsdjl"],
            "Class that does exist, but is no concordance list" => ['MD_STD'],
            "Empty string" => [''],
            "Path traversal" => ['../'],
        ];

    }

    /**
     * Checks that an error is thrown as expected if an invalid
     * concordance list name was provided during setup.
     *
     * @param non-empty-string $class Invalid concordance list name.
     *
     * @return void
     */
    #[DataProvider('invalid_concordance_list_class_provider')]
    public function testInvalidConcordanceListsAreBlockedInConstructor(string $class):void {

        self::expectException(MDpageParameterNotFromListException::class);
        new ConcordanceChecker($class);

    }

    /**
     * Checks that checking some values works.
     *
     * @return void
     */
    public function testEvaluationWorks():void {

        $checker = new ConcordanceChecker("MDConcWeights");

        self::assertEquals(
            [
                'passed' => [
                    'Gramm' => MDWeightUnit::g,
                    'G' => MDWeightUnit::g,
                ],
                'not_passed' => [
                    'fdsafsdafdafdsafdsa'
                ],
            ],
            $checker->evaluate(['Gramm', 'G', 'fdsafsdafdafdsafdsa']),
        );

    }

    /**
     * Checks that getting the available concordance lists works.
     *
     * @return void
     */
    public function testListingConcordanceListsWorks():void {

        $lists = ConcordanceChecker::getLists();
        self::assertNotEmpty($lists);

        foreach ($lists as $list) {

            $checker = new ConcordanceChecker($list);

            self::assertEquals(
                [
                    'passed' => [
                    ],
                    'not_passed' => [
                        'fdsafsdafdafdsafdsa'
                    ],
                ],
                $checker->evaluate(['fdsafsdafdafdsafdsa']),
            );

        }

    }

    /**
     * Valid concordance list provider.
     *
     * @return array<string, array{0: string}>
     */
    public static function valid_concordance_list_provider():array {

        $output = [];

        foreach (ConcordanceChecker::getLists() as $list) {
            $output[$list] = [$list];
        }

        return $output;

    }

    /**
     * Checks that getting the available options for matching.
     *
     * @param string $list List.
     *
     * @return void
     */
    #[DataProvider('valid_concordance_list_provider')]
    public function testListingMatchTargetsByConcordanceList(string $list):void {

        $checker = new ConcordanceChecker($list);
        self::assertIsArray($checker->getMatchOptions());

    }
}
