<?php

namespace Drupal\eca\Plugin\ECA\Event;

use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\eca\Entity\Objects\EcaEvent;
use Drupal\eca\Token\DataProviderInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
 * Interface for ECA event plugins.
 */
interface EventInterface extends PluginFormInterface, ConfigurableInterface, PluginInspectionInterface, DataProviderInterface {

  /**
   * Provides a list of events.
   *
   * @return array[]
   *   The list of events.
   */
  public static function definitions(): array;

  /**
   * Returns the fully-qualified class name of the according system event.
   *
   * @return string
   *   The fully-qualified class name.
   */
  public function eventClass(): string;

  /**
   * Returns the unique ID of the event.
   *
   * @return string
   *   The unique name of the event.
   */
  public function eventName(): string;

  /**
   * Returns the priority for the event subscriber.
   *
   * @return int
   *   The priority for the event subscriber.
   */
  public function subscriberPriority(): int;

  /**
   * Returns a wildcard for appliance checks.
   *
   * The pattern may be arbitrarily contracted for the static
   * ::appliesForWildcard method. It's the responsibility of this implementation
   * that the generated wildcard properly matches up with that appliance method.
   *
   * Wildcards should be as small as possible and their appliance evaluation
   * should be as fast as possible. They will be stored in Drupal state, which
   * then will be used to determine which ECA processes are to be executed.
   *
   * @param string $eca_config_id
   *   The ID of the ECA configuration entity.
   * @param \Drupal\eca\Entity\Objects\EcaEvent $ecaEvent
   *   The modeled event of the ECA configuration entity.
   *
   * @return string
   *   The generated wildcard.
   */
  public function generateWildcard(string $eca_config_id, EcaEvent $ecaEvent): string;

  /**
   * Whether a given wildcard matches up with the given event.
   *
   * @param \Symfony\Contracts\EventDispatcher\Event $event
   *   The given system event to check for.
   * @param string $event_name
   *   The name of the system event.
   * @param string $wildcard
   *   The wildcard that was previously generated by ::generateWildcard
   *   based on current configuration.
   *
   * @return bool
   *   Returns TRUE when the event applies, FALSE otherwise.
   *
   * @see ::generateWildcard()
   */
  public static function appliesForWildcard(Event $event, string $event_name, string $wildcard): bool;

  /**
   * Sets the according system event.
   *
   * @param \Symfony\Contracts\EventDispatcher\Event $event
   *   The system event.
   *
   * @return $this
   */
  public function setEvent(Event $event): EventInterface;

  /**
   * Get the according system event.
   *
   * @return \Symfony\Contracts\EventDispatcher\Event|null
   *   The system event. May be null if not yet known.
   */
  public function getEvent(): ?Event;

  /**
   * Gets the list of tokens.
   *
   * @return \Drupal\eca\Attribute\Token[]
   *   The list of tokens.
   */
  public function getTokens(): array;

  /**
   * Returns whether this event plugin handles exceptions.
   *
   * If so, ECA should not catch them. Defaults to false.
   *
   * @return bool
   *   Whether or not this event plugin handles exceptions.
   */
  public function handleExceptions(): bool;

}
