<?php

namespace Drupal\user_provisioning\ProviderSpecific\Parsers\UserParser;

use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use Drupal\user_provisioning\ProviderSpecific\Parsers\moResourceParserInterface;

/**
 * Parses user resources for SCIM provisioning requests.
 */
class moUserSCIMParser implements moResourceParserInterface {

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

  /**
   * Immutable user provisioning configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   *   Read-only configuration object.
   */
  private ImmutableConfig $config;

  /**
   * Constructs the SCIM user parser.
   */
  public function __construct() {
    $this->moLogger = new moUserProvisioningLogger();
    $this->config = \Drupal::config('user_provisioning.settings');
  }

  /**
   * {@inheritDoc}
   */
  public function search($resource_id): string {
    $this->moLogger->addLog("Creating search request parameter.", __LINE__, __FUNCTION__, __FILE__);
    return 'Users?filter=userName eq "' . $resource_id . '"';
  }

  /**
   * {@inheritDoc}
   */
  public function get($resource_id) {
    // @todo Implement get() method.
  }

  /**
   * {@inheritDoc}
   */
  public function post(EntityInterface $entity) {
    // The bare minimum attributes.
    $post_request_body = $this->getDefaultFields($entity, $this->config->get('mo_user_provisioning_app_name'));
    $this->moLogger->addFormattedLog($post_request_body, __LINE__, __FUNCTION__, __FILE__, 'User create request body: ');

    // Additional attributes
    // consider the mapping made before picking up the additional attributes.
    return $post_request_body;
  }

  /**
   * {@inheritDoc}
   */
  public function put(array $resource) {
    // @todo Implement put() method.
  }

  /**
   * {@inheritDoc}
   */
  public function patch(array $resource) {
    // @todo Implement patch() method.
  }

  /**
   * {@inheritDoc}
   */
  public function delete(array $resource) {
    // @todo Implement delete() method.
  }

  /**
   * Provides the body of the POST request for user.
   *
   * It generates default Drupal user attributes for SCIM payloads.
   *
   * -uuid
   *
   * -Username
   *
   * -Email
   *
   * -Preferred Language
   *
   * -Timezone
   *
   * -Status
   *
   * For AWS SSO, these additional attributes are required.
   *
   * -first name
   *
   * -last name
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Drupal user entity being provisioned.
   * @param string $app_name
   *   Name of the configured app.
   *
   * @return array
   *   The default SCIM field mapping array.
   */
  public function getDefaultFields(EntityInterface $entity, string $app_name): array {
    $mapping_array = json_decode($this->config->get('mo_user_prov_mapping_conf'), TRUE);
    $fields = [
      'externalId' => $entity->uuid(),
      'userName' => $entity->getDisplayName(),
      "emails" => [
        [
          "value" => $entity->getEmail(),
          "type" => "work",
          "primary" => TRUE,
        ],
      ],
      'displayName' => $entity->get($this->getDrupalAttr($mapping_array, 'displayName'))->value,
      'preferredLanguage' => $entity->get($this->getDrupalAttr($mapping_array, 'preferredLanguage'))->value,
      'timezone' => $entity->get($this->getDrupalAttr($mapping_array, 'timezone'))->value,
      'active' => (bool) $entity->get('status')->value,
      'name' => [
        'familyName' => $entity->get($this->getDrupalAttr($mapping_array, 'name.familyName'))->value,
        'givenName' => $entity->get($this->getDrupalAttr($mapping_array, 'name.givenName'))->value,
      ],
    ];
    return $fields;
  }

  /**
   * Returns the mapped Drupal attribute for a given SCIM attribute.
   */
  private function getDrupalAttr($array, $scim_attr) {
    foreach ($array as $item) {
      if ($item['scim_attr'] === $scim_attr) {
        return $item['drupal_attr'];
      }
    }
  }

  /**
   * {@inheritDoc}
   */
  public function deactivate(EntityInterface $entity) {
    // @todo Implement deactivate() method.
  }

}
