<?php

/**
 * @file
 * Non-namespaced code of the Acquia DAM Bulk Import sub-module.
 */

declare(strict_types=1);

use Drupal\Core\Link;
use Drupal\Core\Url;

/**
 * Implements hook_uninstall().
 */
function acquiadam_asset_import_uninstall() {
  // Erase traces from State API.
  // @todo is it used for anything?
  \Drupal::state()->delete('acquia_dam_bulk_import.migration_notice_displayed');

  // Erase the yet unprocessed items from the queue.
  // @see core/modules/update/update.install::update_uninstall()
  $queue = \Drupal::queue('acquia_dam_asset_import');
  $queue->deleteQueue();
}

/**
 * DB update hook #8110.
 *
 * Convert configuration of the contrib `acquiadam_asset_import` module for the
 * `acquia_dam` module.
 */
function acquiadam_asset_import_update_8110() {
  // Clear cache for services to ensure we have the latest versions.
  \Drupal::service('cache.discovery')->deleteAll();
  // Clear cache for routes to ensure we have the latest versions.
  \Drupal::service('router.builder')->rebuild();
  $config_factory = \Drupal::configFactory();
  $logger_channel = \Drupal::service('logger.channel.acquia_dam');
  $old_config_id = 'acquiadam_asset_import.config';

  if (empty($config_factory->listAll($old_config_id))) {
    $output_message = t('No existing configuration of the contrib <code>acquiadam_asset_import</code> module was found to convert for Acquia DAM.');
    $logger_channel->info($output_message);

    return $output_message;
  }

  $old_config = $config_factory->getEditable($old_config_id);
  $old_categories = $old_config->get('categories');

  // Bail out if no categories are defined.
  if (!$old_categories) {
    $output_message = t('No source categories were found listed in the configuration of the contrib <code>acquiadam_asset_import</code> module to import from.');
    $logger_channel->info($output_message);

    return $output_message;
  }

  $old_categories = array_filter(explode("\r\n", $old_categories));

  // Ensure our Client is allowed to call home.
  if (!\Drupal::service('acquia_dam.authentication_service')->isSiteAuthenticated()) {
    $error_message = 'Querying available categories failed as the website seems unauthenticated at the remote Widen system. When authenticated, run database updates again to retry the bulk import settings conversion.';
    $config_page_link = new Link(t('Authenticate'), Url::fromRoute('acquia_dam.config'));
    $logger_channel->info($error_message, ['link' => $config_page_link->toString()]);

    throw new \Exception($error_message);
  }

  $new_config = $config_factory->getEditable('acquiadam_asset_import.settings');
  $new_categories = $new_config->get('categories') ?? [];
  $skipped_categories = $migrated_categories = [];
  // Convert all human labels into UUID, and check their validity.
  foreach ($old_categories as $category_name) {
    $category_uuid = \Drupal::service('acquia_dam.client.factory')->getSiteClient()->convertCategoryNameToUuid($category_name);
    // Don't overwrite categories already existing in module settings or found
    // non-existent.
    if (isset($new_categories[$category_uuid]) || !$category_uuid) {
      $skipped_categories[] = $category_name;
      continue;
    }

    $new_categories[$category_uuid] = [];
    $migrated_categories[] = $category_name;
  }

  $new_config->set('categories', $new_categories);
  $new_config->save();
  // As in the switchover guide, we suggest to delete the source community
  // module without uninstalling it from Drupal (to reserve its existing config
  // for later reading), therefore we became responsible for do its garbage
  // cleaning.
  \Drupal::queue('dam_worker')->deleteQueue();
  $old_config->delete();

  $bulk_import_page_link = new Link(t('Review settings'), Url::fromRoute('acquiadam_asset_import.configuration'));
  $string_translation = \Drupal::translation();
  $output_message = '';

  if (is_array($skipped_categories) && count($skipped_categories) > 0) {
    $skipped_message = $string_translation->formatPlural(
      count($skipped_categories),
      'One category was either unavailable in Acquia DAM or already on the bulk import list: %category_names.',
      '@count categories were either unavailable in Acquia DAM or already on the bulk import list: %category_names.',
      ['%category_names' => implode(', ', $skipped_categories)]
    );
    $logger_channel->info($skipped_message, ['link' => $bulk_import_page_link->toString()]);
    $output_message = PHP_EOL . $skipped_message;
  }

  if (is_array($migrated_categories) && count($migrated_categories) > 0) {
    $migrated_message = $string_translation->formatPlural(
      count($migrated_categories),
      'One category was added to the bulk import list: %category_names.',
      '@count categories were added to the bulk import list: %category_names.',
      ['%category_names' => implode(', ', $migrated_categories)]
    );
    $logger_channel->info($migrated_message, ['link' => $bulk_import_page_link->toString()]);
    $output_message .= PHP_EOL . $migrated_message;
  }

  if (!empty($output_message)) {
    return $output_message;
  }

}

/**
 * DB update hook #8111.
 *
 * Create a new asset_groups config key.
 */
function acquiadam_asset_import_update_8111() {
  $config = \Drupal::configFactory()->getEditable('acquiadam_asset_import.settings');

  if ($config->get('asset_groups') == NULL) {
    $config->set('asset_groups', [])->save();
  }
}

/**
 * DB update hook #8112.
 *
 * Implement update hook to revise asset import settings,
 * ensuring compatibility with subcategories.
 */
function acquiadam_asset_import_update_8112() {
  $config = \Drupal::configFactory()->getEditable('acquiadam_asset_import.settings');
  $categories = $config->get('categories');
  if ($categories) {
    foreach ($categories as $category_uuid => $category) {
      // Update the array key from category uuid to name.
      $category_name = \Drupal::service('acquia_dam.client.factory')->getSiteClient()->convertCategoryUuidToName($category_uuid);
      if ($category_name) {
        $encoded_cat_name = base64_encode($category_name);
        $categories[$encoded_cat_name] = $category;
        unset($categories[$category_uuid]);
      }
    }
    $config->set('categories', $categories)->save();
  }
}

/**
 * DB update hook #8113.
 *
 * Encode existing plain-text category and asset group keys to base64.
 * This ensures compatibility with the new AssetImportUtilityService.
 */
function acquiadam_asset_import_update_8113() {
  // Clear cache for services to ensure we have the latest versions.
  \Drupal::service('cache.discovery')->deleteAll();
  $config = \Drupal::configFactory()->getEditable('acquiadam_asset_import.settings');
  $utility_service = \Drupal::service('acquiadam_asset_import.utility');
  $logger_channel = \Drupal::service('logger.channel.acquia_dam');
  $updated = FALSE;
  $categories_count = 0;
  $asset_groups_count = 0;
  $categories = $config->get('categories');
  if ($categories && is_array($categories)) {
    $encoded_categories = [];
    foreach ($categories as $key => $value) {
      $decoded = base64_decode($key, TRUE);
      if ($decoded === FALSE || base64_encode($decoded) !== $key) {
        $encoded_key = base64_encode($key);
        $encoded_categories[$encoded_key] = $value;
        $categories_count++;
      } else {
        $encoded_categories[$key] = $value;
      }
    }
    $config->set('categories', $encoded_categories);
    $config->save();
    $message = t('Encoded @categories_count category keys and @asset_groups_count asset group keys to base64 format.', [
      '@categories_count' => $categories_count,
      '@asset_groups_count' => $asset_groups_count,
    ]);
    $logger_channel->info($message);
    return $message;
  }
}
