<?php

namespace Drupal\user_provisioning\ProviderSpecific\Factory;

use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use Drupal\user_provisioning\moUserProvisioningConstants;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler\moUserAzureAPIHandler;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler\moUserOktaAPIHandler;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler\moUserSCIMAPIHandler;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler\moUserKeycloakAPIHandler;

use Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser\moUserAzureParser;
use Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser\moUserOktaParser;
use Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser\moUserSCIMParser;
use Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser\moUserKeycloakParser;

use Drupal\user_provisioning\ProviderSpecific\ResponseProcessor\UserResponseProcessor\moUserAzureResponseProcessor;
use Drupal\user_provisioning\ProviderSpecific\ResponseProcessor\UserResponseProcessor\moUserOktaResponseProcessor;
use Drupal\user_provisioning\ProviderSpecific\ResponseProcessor\UserResponseProcessor\moUserSCIMResponseProcessor;
use Drupal\user_provisioning\ProviderSpecific\ResponseProcessor\UserResponseProcessor\moUserKeycloakResponseProcessor;

/**
 * Factory for provider-specific API handlers, parsers, and processors.
 */
class moUserFactory implements moResourceFactoryInterface {

  /**
   * Configured provider application key.
   *
   * @var string
   *   Application key from module configuration.
   */
  private string $appName;

  /**
   * Logger for factory diagnostics.
   *
   * @var \Drupal\user_provisioning\Helpers\moUserProvisioningLogger
   *   Logger utility instance.
   */
  private moUserProvisioningLogger $moLogger;

  /**
   * Constructs the resource factory.
   */
  public function __construct() {
    $app_name = \Drupal::config('user_provisioning.settings')->get('mo_user_provisioning_configured_application');
    if (empty($app_name)) {
      // FIXME: Uncomment the above line after saving the configured app.
      $app_name = moUserProvisioningConstants::DEFAULT_APP;
    }
    $this->appName = $app_name;
    $this->moLogger = new moUserProvisioningLogger();
  }

  /**
   * {@inheritDoc}
   * */
  public function getApiHandler() {
    if ($this->appName == moUserProvisioningConstants::DEFAULT_APP) {
      $this->moLogger->addLog('Returning moUserSCIMAPIHandler for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserSCIMAPIHandler();
    }
    elseif ($this->appName == moUserProvisioningConstants::AZURE_AD) {
      $this->moLogger->addLog('Returning moUserAzureAPIHandler for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserAzureAPIHandler();
    }
    elseif ($this->appName == moUserProvisioningConstants::OKTA) {
      $this->moLogger->addLog('Returning moUserOktaAPIHandler for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserOktaAPIHandler();
    }
    elseif ($this->appName == moUserProvisioningConstants::KEYCLOAK) {
      $this->moLogger->addLog('Returning moUserKeycloakAPIHandler for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserKeycloakAPIHandler();
    }
  }

  /**
   * {@inheritDoc}
   * */
  public function getParser() {
    if ($this->appName == moUserProvisioningConstants::DEFAULT_APP) {
      $this->moLogger->addLog('Returning moUserSCIMParser for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserSCIMParser();
    }
    elseif ($this->appName == moUserProvisioningConstants::AZURE_AD) {
      $this->moLogger->addLog('Returning moUserAzureParser for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserAzureParser();
    }
    elseif ($this->appName == moUserProvisioningConstants::OKTA) {
      $this->moLogger->addLog('Returning moUserOktaParser for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserOktaParser();
    }
    elseif ($this->appName == moUserProvisioningConstants::KEYCLOAK) {
      $this->moLogger->addLog('Returning moUserKeycloakParser for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserKeycloakParser();
    }
  }

  /**
   * {@inheritDoc}
   * */
  public function getResponseProcessor() {
    if ($this->appName == moUserProvisioningConstants::DEFAULT_APP) {
      $this->moLogger->addLog('Returning moUserSCIMResponseProcessor for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserSCIMResponseProcessor();
    }
    elseif ($this->appName == moUserProvisioningConstants::AZURE_AD) {
      $this->moLogger->addLog('Returning moUserAzureResponseProcessor for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserAzureResponseProcessor();
    }
    elseif ($this->appName == moUserProvisioningConstants::OKTA) {
      $this->moLogger->addLog('Returning moUserOktaResponseProcessor for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserOktaResponseProcessor();
    }
    elseif ($this->appName == moUserProvisioningConstants::KEYCLOAK) {
      $this->moLogger->addLog('Returning moUserKeycloakResponseProcessor for app: ' . $this->appName, __LINE__, __FUNCTION__, __FILE__);
      return new moUserKeycloakResponseProcessor();
    }
  }

}
