<?php

declare(strict_types=1);

namespace Drupal\flowdrop_runtime\Service\Storage;

use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Access\AccessResultAllowed;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\flowdrop_job\Constants\JobStatus;
use Drupal\flowdrop_job\FlowDropJobInterface;
use Drupal\flowdrop_pipeline\Constants\PipelineStatus;
use Drupal\flowdrop_pipeline\Entity\FlowDropPipelineInterface;
use Drupal\flowdrop_workflow\FlowDropWorkflowInterface;
use Drupal\user\UserInterface;

/**
 * In-memory implementation of FlowDropPipelineInterface.
 *
 * This value object provides a fast, ephemeral pipeline implementation
 * that doesn't persist to the database. Used by SynchronousOrchestrator
 * for lightweight workflow execution.
 *
 * Note: Methods inherited from Drupal entity interfaces that aren't needed
 * for orchestration are stubbed with sensible defaults or throw exceptions.
 *
 * @internal This class is not part of the public API and may change without notice.
 *
 * @phpstan-ignore-next-line
 */
class InMemoryPipeline implements FlowDropPipelineInterface {

  /**
   * Auto-increment counter for IDs.
   */
  protected static int $idCounter = 0;

  /**
   * The pipeline ID.
   */
  protected string $id;

  /**
   * The pipeline label.
   */
  protected string $label = '';

  /**
   * The workflow ID.
   */
  protected string $workflowId = '';

  /**
   * The pipeline status.
   */
  protected string $status = PipelineStatus::PENDING;

  /**
   * The input data.
   */
  protected array $inputData = [];

  /**
   * The output data.
   */
  protected array $outputData = [];

  /**
   * The error message.
   */
  protected string $errorMessage = '';

  /**
   * The started timestamp.
   */
  protected int $started = 0;

  /**
   * The completed timestamp.
   */
  protected int $completed = 0;

  /**
   * The max concurrent jobs.
   */
  protected int $maxConcurrentJobs = 5;

  /**
   * The job priority strategy.
   */
  protected string $jobPriorityStrategy = 'dependency_order';

  /**
   * The retry strategy.
   */
  protected string $retryStrategy = 'individual';

  /**
   * The execution context.
   */
  protected array $executionContext = [];

  /**
   * The snapshot ID.
   */
  protected ?string $snapshotId = NULL;

  /**
   * The jobs in this pipeline.
   *
   * @var \Drupal\flowdrop_job\FlowDropJobInterface[]
   */
  protected array $jobs = [];

  /**
   * The created timestamp.
   */
  protected int $created;

  /**
   * The changed timestamp.
   */
  protected int $changed;

  /**
   * The owner ID.
   */
  protected int $ownerId = 0;

  /**
   * Constructs a new InMemoryPipeline.
   *
   * @param array $data
   *   Initial data for the pipeline.
   */
  public function __construct(array $data = []) {
    $this->id = 'inmem_' . (++self::$idCounter);
    $this->created = time();
    $this->changed = time();

    if (isset($data['label'])) {
      $this->label = $data['label'];
    }
    if (isset($data['workflow_id'])) {
      $this->workflowId = is_array($data['workflow_id'])
        ? ($data['workflow_id']['target_id'] ?? '')
        : $data['workflow_id'];
    }
    if (isset($data['status'])) {
      $this->status = $data['status'];
    }
    if (isset($data['input_data'])) {
      $this->inputData = is_string($data['input_data'])
        ? json_decode($data['input_data'], TRUE) ?? []
        : $data['input_data'];
    }
    if (isset($data['max_concurrent_jobs'])) {
      $this->maxConcurrentJobs = (int) $data['max_concurrent_jobs'];
    }
    if (isset($data['job_priority_strategy'])) {
      $this->jobPriorityStrategy = $data['job_priority_strategy'];
    }
    if (isset($data['retry_strategy'])) {
      $this->retryStrategy = $data['retry_strategy'];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function id(): string|int|null {
    return $this->id;
  }

  /**
   * {@inheritdoc}
   */
  public function label(): ?string {
    return $this->label;
  }

  /**
   * {@inheritdoc}
   */
  public function getWorkflowId(): string {
    return $this->workflowId;
  }

  /**
   * {@inheritdoc}
   */
  public function setWorkflowId(string $workflow_id): static {
    $this->workflowId = $workflow_id;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getStatus(): string {
    return $this->status;
  }

  /**
   * {@inheritdoc}
   */
  public function setStatus(string $status): static {
    $this->status = $status;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getInputData(): array {
    return $this->inputData;
  }

  /**
   * {@inheritdoc}
   */
  public function setInputData(array $input_data): static {
    $this->inputData = $input_data;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getOutputData(): array {
    return $this->outputData;
  }

  /**
   * {@inheritdoc}
   */
  public function setOutputData(array $output_data): static {
    $this->outputData = $output_data;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getErrorMessage(): string {
    return $this->errorMessage;
  }

  /**
   * {@inheritdoc}
   */
  public function setErrorMessage(string $error_message): static {
    $this->errorMessage = $error_message;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getStarted(): int {
    return $this->started;
  }

  /**
   * {@inheritdoc}
   */
  public function setStarted(int $started): static {
    $this->started = $started;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getCompleted(): int {
    return $this->completed;
  }

  /**
   * {@inheritdoc}
   */
  public function setCompleted(int $completed): static {
    $this->completed = $completed;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getMaxConcurrentJobs(): int {
    return $this->maxConcurrentJobs;
  }

  /**
   * {@inheritdoc}
   */
  public function setMaxConcurrentJobs(int $max_concurrent_jobs): static {
    $this->maxConcurrentJobs = $max_concurrent_jobs;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getJobPriorityStrategy(): string {
    return $this->jobPriorityStrategy;
  }

  /**
   * {@inheritdoc}
   */
  public function setJobPriorityStrategy(string $strategy): static {
    $this->jobPriorityStrategy = $strategy;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getRetryStrategy(): string {
    return $this->retryStrategy;
  }

  /**
   * {@inheritdoc}
   */
  public function setRetryStrategy(string $strategy): static {
    $this->retryStrategy = $strategy;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getExecutionContext(): array {
    return $this->executionContext;
  }

  /**
   * {@inheritdoc}
   */
  public function setExecutionContext(array $context): static {
    $this->executionContext = $context;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function calculateJobCounts(): array {
    $counts = [
      JobStatus::IDLE => 0,
      JobStatus::PENDING => 0,
      JobStatus::RUNNING => 0,
      JobStatus::COMPLETED => 0,
      JobStatus::FAILED => 0,
      JobStatus::CANCELLED => 0,
      JobStatus::SKIPPED => 0,
      JobStatus::INTERRUPTED => 0,
    ];

    foreach ($this->jobs as $job) {
      $status = $job->getStatus();
      if (isset($counts[$status])) {
        $counts[$status]++;
      }
    }

    return $counts;
  }

  /**
   * {@inheritdoc}
   */
  public function isReadyToStart(): bool {
    return $this->status === PipelineStatus::PENDING;
  }

  /**
   * {@inheritdoc}
   */
  public function isRunning(): bool {
    return $this->status === PipelineStatus::RUNNING;
  }

  /**
   * {@inheritdoc}
   */
  public function isCompleted(): bool {
    return $this->status === PipelineStatus::COMPLETED;
  }

  /**
   * {@inheritdoc}
   */
  public function isFailed(): bool {
    return $this->status === PipelineStatus::FAILED;
  }

  /**
   * {@inheritdoc}
   */
  public function isCancelled(): bool {
    return $this->status === PipelineStatus::CANCELLED;
  }

  /**
   * {@inheritdoc}
   */
  public function isPaused(): bool {
    return $this->status === PipelineStatus::PAUSED;
  }

  /**
   * {@inheritdoc}
   */
  public function markAsStarted(): static {
    $this->status = PipelineStatus::RUNNING;
    $this->started = time();
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function markAsCompleted(array $output_data = []): static {
    $this->status = PipelineStatus::COMPLETED;
    $this->outputData = $output_data;
    $this->completed = time();
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function markAsFailed(string $error_message = ''): static {
    $this->status = PipelineStatus::FAILED;
    $this->errorMessage = $error_message;
    $this->completed = time();
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function markAsCancelled(): static {
    $this->status = PipelineStatus::CANCELLED;
    $this->completed = time();
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function pause(): static {
    $this->status = PipelineStatus::PAUSED;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function resume(): static {
    $this->status = PipelineStatus::RUNNING;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getWorkflow(): ?FlowDropWorkflowInterface {
    // In-memory pipelines don't load workflow entities.
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getJobs(): array {
    return $this->jobs;
  }

  /**
   * {@inheritdoc}
   */
  public function getJobsByStatus(string $status): array {
    return array_filter($this->jobs, fn($job) => $job->getStatus() === $status);
  }

  /**
   * {@inheritdoc}
   */
  public function hasRunningJobs(): bool {
    return !empty($this->getJobsByStatus(JobStatus::RUNNING));
  }

  /**
   * {@inheritdoc}
   */
  public function hasPendingJobs(): bool {
    return !empty($this->getJobsByStatus(JobStatus::PENDING));
  }

  /**
   * {@inheritdoc}
   */
  public function hasIdleJobs(): bool {
    return !empty($this->getJobsByStatus(JobStatus::IDLE));
  }

  /**
   * {@inheritdoc}
   */
  public function hasUnfinishedJobs(): bool {
    foreach ($this->jobs as $job) {
      $status = $job->getStatus();
      if (in_array($status, JobStatus::activeStatuses(), TRUE)) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function hasInterruptedJobs(): bool {
    return !empty($this->getJobsByStatus(JobStatus::INTERRUPTED));
  }

  /**
   * {@inheritdoc}
   */
  public function allJobsCompleted(): bool {
    $terminalStatuses = [JobStatus::COMPLETED, JobStatus::FAILED, JobStatus::CANCELLED, JobStatus::SKIPPED];
    foreach ($this->jobs as $job) {
      if (!in_array($job->getStatus(), $terminalStatuses, TRUE)) {
        return FALSE;
      }
    }
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function hasFailedJobs(): bool {
    return !empty($this->getJobsByStatus(JobStatus::FAILED));
  }

  /**
   * {@inheritdoc}
   */
  public function addJob(FlowDropJobInterface $job): static {
    $jobId = $job->id();
    if ($jobId !== NULL) {
      $this->jobs[$jobId] = $job;
    }
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function removeJob(FlowDropJobInterface $job): static {
    $jobId = $job->id();
    if ($jobId !== NULL) {
      unset($this->jobs[$jobId]);
    }
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function clearJobs(): static {
    $this->jobs = [];
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getSnapshotId(): ?string {
    return $this->snapshotId;
  }

  /**
   * {@inheritdoc}
   */
  public function setSnapshotId(?string $snapshot_id): static {
    $this->snapshotId = $snapshot_id;
    $this->changed = time();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getSnapshot(): ?object {
    // In-memory pipelines don't load snapshot entities.
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage): void {
    // No-op for in-memory storage.
  }

  /**
   * {@inheritdoc}
   */
  public function save(): int {
    // In-memory - no actual save, return SAVED_UPDATED.
    $this->changed = time();
    return 2;
  }

  /**
   * {@inheritdoc}
   */
  public function delete(): void {
    // No-op for in-memory storage.
  }

  // =========================================================================
  // EntityOwnerInterface methods
  // =========================================================================

  /**
   * {@inheritdoc}
   */
  public function getOwner(): ?UserInterface {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account): static {
    $this->ownerId = (int) $account->id();
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId(): ?int {
    return $this->ownerId ?: NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid): static {
    $this->ownerId = (int) $uid;
    return $this;
  }

  // =========================================================================
  // EntityChangedInterface methods
  // =========================================================================

  /**
   * {@inheritdoc}
   */
  public function getChangedTime(): int {
    return $this->changed;
  }

  /**
   * {@inheritdoc}
   */
  public function setChangedTime($timestamp): static {
    $this->changed = (int) $timestamp;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getChangedTimeAcrossTranslations(): int {
    return $this->changed;
  }

  // =========================================================================
  // ContentEntityInterface methods (stubbed)
  // =========================================================================

  /**
   * {@inheritdoc}
   */
  public function hasField($field_name): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function get($field_name): FieldItemListInterface {
    throw new \RuntimeException("InMemoryPipeline does not support field access via get()");
  }

  /**
   * {@inheritdoc}
   */
  public function set($field_name, $value, $notify = TRUE): static {
    throw new \RuntimeException("InMemoryPipeline does not support field access via set()");
  }

  /**
   * {@inheritdoc}
   */
  public function getFields($include_computed = TRUE): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslatableFields($include_computed = TRUE): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldDefinition($name): ?FieldDefinitionInterface {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldDefinitions(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function toArray(): array {
    return [
      'id' => $this->id,
      'label' => $this->label,
      'workflow_id' => $this->workflowId,
      'status' => $this->status,
      'input_data' => $this->inputData,
      'output_data' => $this->outputData,
      'error_message' => $this->errorMessage,
      'started' => $this->started,
      'completed' => $this->completed,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function onChange($name): void {
    $this->changed = time();
  }

  /**
   * {@inheritdoc}
   */
  public function validate(): object {
    throw new \RuntimeException("InMemoryPipeline does not support validation");
  }

  /**
   * {@inheritdoc}
   */
  public function isValidationRequired(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function setValidationRequired($required): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function uuid(): ?string {
    return $this->id;
  }

  /**
   * {@inheritdoc}
   */
  public function bundle(): string {
    return 'default';
  }

  /**
   * {@inheritdoc}
   */
  public function isNew(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function enforceIsNew($value = TRUE): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityTypeId(): string {
    return 'flowdrop_pipeline';
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityType(): EntityTypeInterface {
    throw new \RuntimeException("InMemoryPipeline does not support getEntityType()");
  }

  /**
   * {@inheritdoc}
   */
  public function language(): LanguageInterface {
    throw new \RuntimeException("InMemoryPipeline does not support language()");
  }

  /**
   * {@inheritdoc}
   */
  public function isNewTranslation(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function isNewRevision(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function setNewRevision($value = TRUE): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public function isDefaultRevision($new_value = NULL): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function wasDefaultRevision(): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function isLatestRevision(): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function isLatestTranslationAffectedRevision(): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getRevisionId(): ?int {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getLoadedRevisionId(): ?int {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function updateLoadedRevisionId(): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function isTranslatable(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function isDefaultTranslation(): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslationLanguages($include_default = TRUE): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslation($langcode): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getUntranslated(): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function hasTranslation($langcode): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function hasTranslationChanges(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function addTranslation($langcode, array $values = []): static {
    throw new \RuntimeException("InMemoryPipeline does not support translations");
  }

  /**
   * {@inheritdoc}
   */
  public function removeTranslation($langcode): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public function isRevisionTranslationAffected(): ?bool {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function setRevisionTranslationAffected($affected): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function isRevisionTranslationAffectedEnforced(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function setRevisionTranslationAffectedEnforced($enforced): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function access($operation, ?AccountInterface $account = NULL, $return_as_object = FALSE): AccessResultInterface|bool {
    return $return_as_object ? new AccessResultAllowed() : TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge(): int {
    return 0;
  }

  /**
   * {@inheritdoc}
   */
  public function toLink($text = NULL, $rel = 'canonical', array $options = []): object {
    throw new \RuntimeException("InMemoryPipeline does not support toLink()");
  }

  /**
   * {@inheritdoc}
   */
  public function toUrl($rel = 'canonical', array $options = []): object {
    throw new \RuntimeException("InMemoryPipeline does not support toUrl()");
  }

  /**
   * {@inheritdoc}
   */
  public function hasLinkTemplate($key): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function uriRelationships(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public static function load($id): ?static {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function loadMultiple(?array $ids = NULL): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public static function create(array $values = []): static {
    return new static($values);
  }

  /**
   * {@inheritdoc}
   */
  public function createDuplicate(): static {
    $duplicate = clone $this;
    $duplicate->id = 'inmem_' . (++self::$idCounter);
    return $duplicate;
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigDependencyKey(): string {
    return 'content';
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigDependencyName(): string {
    return $this->getEntityTypeId() . ':' . $this->id();
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigTarget(): string {
    return $this->getEntityTypeId() . ':' . $this->uuid();
  }

  /**
   * {@inheritdoc}
   */
  public function getOriginalId(): ?string {
    return $this->id;
  }

  /**
   * {@inheritdoc}
   */
  public function setOriginalId($id): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getTypedData(): TypedDataInterface {
    throw new \RuntimeException("InMemoryPipeline does not support getTypedData()");
  }

  /**
   * {@inheritdoc}
   */
  public function postCreate(EntityStorageInterface $storage): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage, array &$values): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public static function preDelete(EntityStorageInterface $storage, array $entities): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public static function postDelete(EntityStorageInterface $storage, array $entities): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public static function postLoad(EntityStorageInterface $storage, array &$entities): void {
    // No-op.
  }

  /**
   * {@inheritdoc}
   */
  public function referencedEntities(): array {
    return [];
  }

  // =========================================================================
  // Additional interface methods
  // =========================================================================

  /**
   * {@inheritdoc}
   */
  public function addCacheContexts(array $cache_contexts): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addCacheTags(array $cache_tags): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addCacheableDependency($other_object): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function mergeCacheMaxAge($max_age): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getBundleEntity(): ?EntityInterface {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTagsToInvalidate(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getOriginal(): ?static {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function setOriginal(?object $entity): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function isDefaultTranslationAffectedOnly(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function isSyncing(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function setSyncing($syncing): static {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record): void {
    // No-op.
  }

}
