<?php

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\user_provisioning\Helpers\moProviderSpecificProvisioning;
use Drupal\user_provisioning\moUserProvisioningOperationsHandler;

function user_provisioning_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
    $enable_auto_provisioning = Drupal::config('azure_ad.settings')->get('azure_ad_automatic_provisioning_checkbox');
    $enable_auto_provisioning_okta = Drupal::config('okta_user_sync.settings')->get('okta_user_sync_enable_automatic_provisioning_checkbox');

    if ($enable_auto_provisioning ||$enable_auto_provisioning_okta ){
        if ($form_id == 'user_register_form'){
            array_unshift($form['#validate'], 'user_provisioning_form_user_register_form_alter_submit');
        }
    }
}

/**
 * Implements hook_help().
 */
function user_provisioning_help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match) {
    switch ($route_name) {
        case 'help.page.user_provisioning':
            $url = Url::fromRoute('user.admin_index')->toString();
            $moduleLink = $url . '/user_provisioning/provisioning';

            $moduleLandingPage = 'https://plugins.miniorange.com/drupal-user-provisioning-and-sync';
            $setup_guides = 'https://plugins.miniorange.com/drupal-user-provisioning-scim-setup-guides';

            $output = '';
            $output .= '<h3>' . t('About <a target="_blank" href="' . $moduleLandingPage . '">[Know more]</a>') . '</h3>';
            $output .= '<p>' . t('User provisioning and syncing is the process of Creating, Reading, and Updating a user\'s account information and access policies for multiple applications and systems simultaneously. This solution is intended to automate the provisioning/de-provisioning process while also maintaining a single system to manage permissions and groups.') . '</p>';
            $output .= '<h3>' . t('Configuration') . '</h3>';
            $output .= '<p>' . t('Configure miniOrange User Provisioning under Configuration » <a target = "_blank" href=" ' . $url . ' ">People</a> » <a target = "_blank" href=" ' . $moduleLink . ' ">miniOrange User Provisioning</a>:') . '</p>';
            $output .= '<p>
                           <ol>
                              <li>' . t('In the <a target="_blank" href="' . $moduleLink . '">User Provisioning </a> of the module, you can configure your SCIM Server. You can also refer these <a target="_blank" href="' . $setup_guides . '">Setup Guides</a>.') . '</li>
                              <li>' . t('Once the configuration is done, please click on the <strong>Test Configuration</strong> button on the same page to confirm the configurations.') . '</li>
                              <li>' . t('If you need any assistance, just send us a query at <a class="button button--primary button--small" href="mailto:drupalsupport@xecurify.com?subject=Drupal User Provisioning module - Need assistance">drupalsupport@xecurify.com</a> and we will get back to you very soon.') . '</li>
                           </ol>
                        </p>';
            $output .= '<h3>' . t('Setup Guides') . '</h3>';
            $output .= '<p>' . t('Click <a target="_blank" href="' . $setup_guides . '">here</a> to check out the setup guides for different SCIM providers.') . '</p>';

            return $output;
    }
}

function user_provisioning_form_user_register_form_alter_submit(&$form, FormStateInterface $form_state){
    $prov_specific = new moProviderSpecificProvisioning();
    $form_values = $form_state->getValues();
    $encrypted_data = $prov_specific->encrypt_data($form_values['pass'], $form_values['name']);
    Drupal::configFactory()->getEditable('azure_ad.settings')->set( 'mo_azure_ad_'.$form_values['name'].'_dependency', $encrypted_data)->save();
    Drupal::configFactory()->getEditable('okta_user_sync.settings')->set( 'mo_okta_'.$form_values['name'].'_dependency', $encrypted_data)->save();

}

/**
 * Implements hook_entity_insert().
 */
function user_provisioning_entity_insert(EntityInterface $entity)
{
    //Need to add this check because while uploading the profile picture, it breaks the flow.
    if ($entity->bundle() == 'user') {
        $config = \Drupal::config('user_provisioning.settings');
        $config_azure = \Drupal::config('azure_ad.settings');
        $config_okta = \Drupal::config('okta_user_sync.settings');

        if (($config->get('mo_user_prov_scim_client_enable_api_integration') && $config->get('mo_user_provisioning_create_user') && $config->get('event_based_provisioning')) || $config_azure->get('azure_ad_automatic_provisioning_checkbox')|| $config_okta->get('okta_user_sync_enable_automatic_provisioning_checkbox')) {
            $operation_handler = new moUserProvisioningOperationsHandler($entity);
            try {
                $response = $operation_handler->insert();
            } catch (Exception $exception) {
                //TODO Add this operation in the Queue to performed on cron or scheduler
                \Drupal::logger('user_provisioning')->error($exception->getMessage());
            }
        }
    }
}

/**
 * Implements hook_views_data().
 */
function user_provisioning_views_data()
{
    $data = [];
    $data['mo_user_provisioning_audits_and_logs'] = [];
    $data['mo_user_provisioning_audits_and_logs']['table'] = [
        'group' => t('Audits and Logs table'),
        'provider' => 'user_provisioning',
        'base' => [
            'field' => 'uid',
            'title' => t('Audits and Logs table'),
            'help' => t('Audits and Logs table contains logs of the users who are performing the provisioning using User Provisioning and Sync module.'),
        ]
    ];

    $data['mo_user_provisioning_audits_and_logs']['uid'] = [
        'title' => t('ID of the user'),
        'help' => t('ID of the user'),
        'relationship' => [
            'base' => 'people',
            'base field' => 'uid',
            'id' => 'standard',
            'label' => t('UID'),
        ],
        'field' => [
            'id' => 'numeric',
        ],
        'sort' => [
            'id' => 'standard',
        ],
        'filter' => [
            'id' => 'numeric',
        ],
        'argument' => [
            'id' => 'numeric',
        ],
    ];

    $data['mo_user_provisioning_audits_and_logs']['name'] = [
        'title' => t('Username'),
        'help' => t('Username of the user'),
        'field' => [
            'id' => 'standard',
        ],
        'sort' => [
            'id' => 'standard',
        ],
        'filter' => [
            'id' => 'string',
        ],
        'argument' => [
            'id' => 'string',
        ],
    ];

    $data['mo_user_provisioning_audits_and_logs']['created'] = [
        'title' => t('Date'),
        'help' => t('Date of the operation performed'),
        'field' => [
            'id' => 'date',
        ],
        'sort' => [
            'id' => 'date',
        ],
        'filter' => [
            'id' => 'date',
        ],
    ];

    $data['mo_user_provisioning_audits_and_logs']['operation'] = [
        'title' => t('Operation'),
        'help' => t('Operation performed of the user'),
        'field' => [
            'id' => 'standard',
        ],
        'sort' => [
            'id' => 'standard',
        ],
        'filter' => [
            'id' => 'string',
        ],
        'argument' => [
            'id' => 'string',
        ],
    ];

    $data['mo_user_provisioning_audits_and_logs']['status'] = [
        'title' => t('Status'),
        'help' => t('Status of provisioning of the user'),
        'field' => [
            'id' => 'boolean',
        ],
        'sort' => [
            'id' => 'standard',
        ],
        'filter' => [
            'id' => 'boolean',
            'label' => t('Status'),
            'type' => 'yes-no',
            'use_equal' => TRUE,
        ],
    ];

    return $data;
}

/**
 * Implements hook_entity_update().
 */

function user_provisioning_entity_update(EntityInterface $entity)
{
  if($entity->bundle() == 'user'){
    if($entity->isBlocked()){
      $config_okta = \Drupal::config('okta_user_sync.settings');
      if($config_okta->get('okta_user_sync_deactivate_user_automatic_provisioning_checkbox')){
        $operation_handler = new moUserProvisioningOperationsHandler($entity);
        try {
          $response = $operation_handler->deactivate();
        } catch (Exception $exception) {
          //TODO Add this operation in the Queue to performed on cron or scheduler
          \Drupal::logger('user_provisioning')->error($exception->getMessage());
        }
      }
    }
  }
}

/**
 * Implements hook_theme().
 */
function user_provisioning_theme($existing, $type, $theme, $path)
{
    return [
        'skipped-feedback' => [
            'variables' => ['module_info' => NULL,],
        ],
        'uninstall-feedback' => [
            'variables' => ['details' => NULL,],],
    ];
}

function uninstall_user_provisioning_custom_validate(&$form, FormStateInterface &$form_state) {
  $post         = \Drupal::request()->request->all();
  $skip         = isset($post['skip']) ? 1 : 0 ;
  if(!$skip) {
    $email = $form_state->getValue('uninstall_email');
    $reason = $form_state->getValue('uninstall_reason');

    if(!isset($reason) && empty($email)) {
      $form_state->setErrorByName(
          'uninstall_email',
          t('Email field is required'));
      $form_state->setErrorByName(
          'uninstall_reason',
          t('Reason field is required'));
    }
    else if(!isset($reason)) {
      $form_state->setErrorByName(
          'uninstall_reason',
          t('Reason field is required'));
    }
    else if (empty($email)) {
      $form_state->setErrorByName(
          'uninstall_email',
          t('Email field is required'));
    }
  }
}