<?php

namespace Seo\Extractor;

use AutoAdmin\Bundle\Seo\Extractor\ExtractorInterface;
use AutoAdmin\Bundle\Seo\Extractor\ExtractorManager;
use AutoAdmin\Bundle\Seo\Model\SeoPage;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use stdClass;
use Symfony\Component\HttpFoundation\Request;

class ExtractorManagerTest extends TestCase
{
    /**
     * @dataProvider extractProvider
     */
    public function testExtract(SeoPage $original, array $extractors, SeoPage $expected): void
    {
        $extractorManager = $this->getMockBuilder(ExtractorManager::class)
            ->disableOriginalConstructor()
            ->getMock();

        $reflection = new ReflectionClass(ExtractorManager::class);
        $reflection->getProperty('extractors')->setValue($extractorManager, $extractors);

        $method = $reflection->getMethod('extract');

        $result = $method->invokeArgs($extractorManager, [new Request(), new stdClass(), $original]);

        $this->assertEquals($expected, $result);
    }

    private function extractProvider(): array
    {
        $original = new SeoPage();
        $original->setTitle('Original Title');

        $override = new SeoPage();
        $override->setTitle('Override Title');

        return [
            'no extractors' => [
                'original' => $original,
                'extractors' => [],
                'expected' => $original,
            ],
            'no matching extractors' => [
                'original' => $original,
                'extractors' => [
                    $this->createExtractor(false, $override),
                ],
                'expected' => $original,
            ],
            'extractor match' => [
                'original' => $original,
                'extractors' => [
                    $this->createExtractor(true, $override),
                ],
                'expected' => $override,
            ],
        ];
    }

    private function createExtractor(bool $supports, SeoPage $seo): ExtractorInterface
    {
        $extractor = $this->getMockBuilder(ExtractorInterface::class)
            ->getMock();

        $extractor->method('supports')
            ->willReturn($supports);

        $extractor->method('extract')
            ->willReturn($seo);

        return $extractor;
    }
}
