<?php

declare(strict_types=1);

namespace Drupal\Tests\netforum\Unit;

use Drupal\netforum\NetForumXmlServiceOptions;
use Drupal\netforum\SoapHttpAuthenticationType;
use Drupal\netforum\SoapWsdlCacheType;
use Drupal\netforum\xWeb\AuthTokenHandlerInterface;
use Drupal\netforum\xWeb\NetForumXml;
use Drupal\Tests\UnitTestCase;
use Psr\Log\LoggerInterface;

/**
 * @coversDefaultClass \Drupal\netforum\NetForumXmlServiceOptions
 * @group netforum
 */
class NetForumXmlServiceOptionsTest extends UnitTestCase {

  private NetForumXmlServiceOptions $options;

  /**
   * @covers ::setWsdlCache
   * @covers ::getWsdlCache
   */
  public function testWsdlCache(): void {
    $this->assertNull($this->options->getWsdlCache());
    $this->options->setWsdlCache(SoapWsdlCacheType::None);
    $this->assertEquals(SoapWsdlCacheType::None, $this->options->getWsdlCache());
  }

  /**
   * @covers ::setClassMap
   * @covers ::getClassMap
   */
  public function testClassMap(): void {
    $classmap = ['test' => 'TestClass'];
    $this->options->setClassMap($classmap);
    $this->assertEquals($classmap, $this->options->getClassMap());
  }

  /**
   * @covers ::setWsdl
   * @covers ::getWsdl
   */
  public function testWsdl(): void {
    $wsdl = 'http://example.com/wsdl';
    $this->options->setWsdl($wsdl);
    $this->assertEquals($wsdl, $this->options->getWsdl());
  }

  /**
   * @covers ::setEndpoint
   * @covers ::getEndpoint
   */
  public function testEndpoint(): void {
    $endpoint = 'http://example.com/endpoint';
    $this->options->setEndpoint($endpoint);
    $this->assertEquals($endpoint, $this->options->getEndpoint());
  }

  /**
   * @covers ::setUserAgent
   * @covers ::getUserAgent
   */
  public function testUserAgent(): void {
    $userAgent = 'TestAgent/1.0';
    $this->options->setUserAgent($userAgent);
    $this->assertEquals($userAgent, $this->options->getUserAgent());
  }

  /**
   * @covers ::setRequestTimeout
   * @covers ::getRequestTimeout
   */
  public function testRequestTimeout(): void {
    $timeout = 30;
    $this->options->setRequestTimeout($timeout);
    $this->assertEquals($timeout, $this->options->getRequestTimeout());
  }

  /**
   * @covers ::setHttpKeepalive
   * @covers ::getHttpKeepalive
   */
  public function testHttpKeepalive(): void {
    $this->options->setHttpKeepalive(TRUE);
    $this->assertTrue($this->options->getHttpKeepalive());
    $this->options->setHttpKeepalive(FALSE);
    $this->assertFalse($this->options->getHttpKeepalive());
  }

  /**
   * @covers ::setHttpCompression
   * @covers ::getHttpCompression
   */
  public function testHttpCompression(): void {
    $this->options->setHttpCompression(TRUE);
    $this->assertTrue($this->options->getHttpCompression());
    $this->options->setHttpCompression(FALSE);
    $this->assertFalse($this->options->getHttpCompression());
  }

  /**
   * @covers ::setVerifyTls
   * @covers ::getVerifyTls
   */
  public function testVerifyTls(): void {
    $this->options->setVerifyTls(FALSE);
    $this->assertFalse($this->options->getVerifyTls());
    $this->options->setVerifyTls(TRUE);
    $this->assertTrue($this->options->getVerifyTls());
  }

  /**
   * @covers ::setHttpAuth
   * @covers ::getHttpAuthEnabled
   * @covers ::getHttpAuthType
   * @covers ::getHttpAuthUsername
   * @covers ::getHttpAuthPassword
   */
  public function testHttpAuth(): void {
    $this->options->setHttpAuth(TRUE, SoapHttpAuthenticationType::Basic, 'user', 'pass');
    $this->assertTrue($this->options->getHttpAuthEnabled());
    $this->assertEquals(SoapHttpAuthenticationType::Basic, $this->options->getHttpAuthType());
    $this->assertEquals('user', $this->options->getHttpAuthUsername());
    $this->assertEquals('pass', $this->options->getHttpAuthPassword());

    $this->options->setHttpAuth(FALSE);
    $this->assertFalse($this->options->getHttpAuthEnabled());
    $this->assertNull($this->options->getHttpAuthType());
    $this->assertNull($this->options->getHttpAuthUsername());
    $this->assertNull($this->options->getHttpAuthPassword());
  }

  /**
   * @covers ::setProxyServer
   * @covers ::getProxyServerEnabled
   * @covers ::getProxyServerHostname
   * @covers ::getProxyServerPort
   * @covers ::getProxyServerUsername
   * @covers ::getProxyServerPassword
   */
  public function testProxyServer(): void {
    $this->options->setProxyServer(TRUE, 'proxy.example.com', 8080, 'proxyuser', 'proxypass');
    $this->assertTrue($this->options->getProxyServerEnabled());
    $this->assertEquals('proxy.example.com', $this->options->getProxyServerHostname());
    $this->assertEquals(8080, $this->options->getProxyServerPort());
    $this->assertEquals('proxyuser', $this->options->getProxyServerUsername());
    $this->assertEquals('proxypass', $this->options->getProxyServerPassword());

    $this->options->setProxyServer(FALSE, '', 0);
    $this->assertFalse($this->options->getProxyServerEnabled());
    $this->assertNull($this->options->getProxyServerHostname());
    $this->assertNull($this->options->getProxyServerPort());
    $this->assertNull($this->options->getProxyServerUsername());
    $this->assertNull($this->options->getProxyServerPassword());
  }

  /**
   * @covers ::setAuthTokenHandler
   * @covers ::getAuthTokenHandler
   */
  public function testAuthTokenHandler(): void {
    /** @var \Drupal\netforum\xWeb\AuthTokenHandlerInterface|\PHPUnit\Framework\MockObject\MockObject $handler */
    $handler = $this->createMock(AuthTokenHandlerInterface::class);
    $this->options->setAuthTokenHandler($handler);
    $this->assertSame($handler, $this->options->getAuthTokenHandler());
  }

  /**
   * @covers ::setLogHandler
   * @covers ::getLogHandler
   */
  public function testLogHandler(): void {
    /** @var \Psr\Log\LoggerInterface|\PHPUnit\Framework\MockObject\MockObject $logger */
    $logger = $this->createMock(LoggerInterface::class);
    $this->options->setLogHandler($logger);
    $this->assertSame($logger, $this->options->getLogHandler());
  }

  /**
   * @covers ::setDebugLogAll
   * @covers ::getDebugLogAll
   */
  public function testDebugLogAll(): void {
    $this->assertNull($this->options->getDebugLogAll());
    $this->options->setDebugLogAll(TRUE);
    $this->assertTrue($this->options->getDebugLogAll());
    $this->options->setDebugLogAll(FALSE);
    $this->assertFalse($this->options->getDebugLogAll());
  }

  /**
   * @covers ::getOptions
   */
  public function testGetOptions(): void {
    $options = $this->options->getOptions();
    $this->assertArrayHasKey(NetForumXml::WSDL_STREAM_CONTEXT, $options);
  }

  protected function setUp(): void {
    parent::setUp();

    $this->options = new NetForumXmlServiceOptions();
  }

}
