<?php

namespace Drupal\eb\PluginBase;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\eb\PluginInterfaces\EbExtensionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base class for Entity Builder Extension plugins.
 *
 * Provides default implementations for optional methods. Extensions must
 * implement buildOperations() to convert definitions to operations.
 *
 * @see \Drupal\eb\Attribute\EbExtension
 * @see \Drupal\eb\PluginInterfaces\EbExtensionInterface
 */
abstract class EbExtensionBase extends PluginBase implements
  EbExtensionInterface,
  ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   *
   * @return static
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition,
  ) {
    // @phpstan-ignore-next-line
    return new static($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function buildOperations(array $data): array {
    // Default: no operations to contribute.
    // Extensions should override this method.
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getOperationDependencies(array $operation, array $context): array {
    // Default: no additional dependencies.
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function detectChanges(array $operation, array $context): ?string {
    // Default: defer to core change detection.
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function checkDependencies(array $dependencyKeys): array {
    // Default: cannot verify any dependencies.
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function appliesTo(array $operation): bool {
    $operation_type = $operation['operation'] ?? '';
    return in_array($operation_type, $this->getOperations(), TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function getYamlKeys(): array {
    return $this->pluginDefinition['yaml_keys'] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function getOperations(): array {
    return $this->pluginDefinition['operations'] ?? [];
  }

  /**
   * Gets the module dependencies for this extension.
   *
   * @return array
   *   Array of module names.
   */
  public function getModuleDependencies(): array {
    return $this->pluginDefinition['module_dependencies'] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function extractConfig(string $entityTypeId, string $bundle): array {
    // Default: no configuration to extract.
    return [];
  }

}
