<?php

declare(strict_types=1);

namespace Drupal\Tests\visitors\Unit\Service;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\visitors\Service\HostnameMatcherServiceBase;

/**
 * Tests the HostnameMatcherServiceBase class.
 *
 * @group visitors
 * @coversDefaultClass \Drupal\visitors\Service\HostnameMatcherServiceBase
 */
class HostnameMatcherServiceBaseTest extends UnitTestCase {

  /**
   * The config factory mock.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  private ConfigFactoryInterface $configFactory;

  /**
   * The test service instance.
   *
   * @var \Drupal\visitors\Service\HostnameMatcherServiceBase
   */
  private HostnameMatcherServiceBase $testService;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->configFactory = $this->createMock(ConfigFactoryInterface::class);
    $this->testService = new class($this->configFactory) extends HostnameMatcherServiceBase {

      /**
       * {@inheritdoc}
       */
      protected function getConfig(): array {
        return [
          [
            'label' => 'Test Service 1',
            'hosts' => ['test1.com', 'test1.org'],
          ],
          [
            'label' => 'Test Service 2',
            'hosts' => ['test2.com'],
          ],
        ];
      }

    };
  }

  /**
   * Tests successful hostname matching.
   *
   * @covers ::match
   */
  public function testMatchSuccess(): void {
    $result = $this->testService->match('test1.com');
    $this->assertEquals('Test Service 1', $result);

    $result = $this->testService->match('test1.org');
    $this->assertEquals('Test Service 1', $result);

    $result = $this->testService->match('test2.com');
    $this->assertEquals('Test Service 2', $result);
  }

  /**
   * Tests case-insensitive hostname matching.
   *
   * @covers ::match
   */
  public function testMatchCaseInsensitive(): void {
    $result = $this->testService->match('TEST1.COM');
    $this->assertEquals('Test Service 1', $result);

    $result = $this->testService->match('Test1.Org');
    $this->assertEquals('Test Service 1', $result);
  }

  /**
   * Tests hostname matching with whitespace.
   *
   * @covers ::match
   */
  public function testMatchWithWhitespace(): void {
    $result = $this->testService->match('  test1.com  ');
    $this->assertEquals('Test Service 1', $result);
  }

  /**
   * Tests failed hostname matching.
   *
   * @covers ::match
   */
  public function testMatchFailure(): void {
    $result = $this->testService->match('nonexistent.com');
    $this->assertNull($result);

    $result = $this->testService->match('test3.com');
    $this->assertNull($result);
  }

  /**
   * Tests empty hostname handling.
   *
   * @covers ::match
   */
  public function testMatchEmptyHostname(): void {
    $result = $this->testService->match('');
    $this->assertNull($result);

    $result = $this->testService->match('   ');
    $this->assertNull($result);
  }

}
