<?php

declare(strict_types=1);

namespace Drupal\netforum\xWeb;

use WsdlToPhp\PackageBase\AbstractSoapClientBase;

/**
 * Base class to allow for overriding SoapClient used by services.
 */
class SoapClientBase extends AbstractSoapClientBase {

  public const DEFAULT_SOAP_CLIENT_CLASS = 'Drupal\netforum\xWeb\SoapClient';

  public function getSoapClientClassName(?string $soapClientClassName = NULL): string {
    return parent::getSoapClientClassName(static::DEFAULT_SOAP_CLIENT_CLASS);
  }

  /**
   * This exists to work around __default_headers being private by overring the
   * parent functionality.
   *
   * @todo Remove this once https://github.com/WsdlToPhp/PackageBase/issues/49
   *   is fixed.
   */
  public function setSoapHeader(string $namespace, string $name, $data, bool $mustUnderstand = FALSE, ?string $actor = NULL): self {
    /** @var \Drupal\netforum\xWeb\SoapClient|null $soapClient */
    $soapClient = $this->getSoapClient();
    if ($soapClient instanceof SoapClient) {
      static::setSoapHeaderOn($soapClient, $namespace, $name, $data, $mustUnderstand, $actor);
    }

    return $this;
  }

  public static function setSoapHeaderOn(SoapClient $soap_client, string $namespace, string $name, mixed $data, bool $mustUnderstand = FALSE, ?string $actor = NULL): bool {
    $defaultHeaders = is_array($soap_client->__getSoapHeaders()) ? $soap_client->__getSoapHeaders() : [];
    foreach ($defaultHeaders as $index => $soapHeader) {
      if ($soapHeader->name === $name) {
        unset($defaultHeaders[$index]);
        break;
      }
    }

    $soap_client->__setSoapheaders(NULL);

    if (!empty($actor)) {
      $defaultHeaders[] = new \SoapHeader($namespace, $name, $data, $mustUnderstand, $actor);
    }
    else {
      $defaultHeaders[] = new \SoapHeader($namespace, $name, $data, $mustUnderstand);
    }

    return $soap_client->__setSoapheaders($defaultHeaders);
  }

}
