<?php

declare(strict_types=1);

namespace Drupal\flowdrop_memory\Plugin\MemoryBackend;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\flowdrop_memory\Attribute\MemoryBackend;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * In-process, per-request memory backend.
 *
 * Stores values in a PHP static array. Data is lost when the request ends
 * or the process terminates. Useful for testing, development, and ephemeral
 * within-request workflows.
 *
 * @internal
 */
#[MemoryBackend(
  id: 'static',
  label: new TranslatableMarkup('Static (In-Process)'),
  description: 'Per-request in-memory storage. Data is lost when the request ends. Suitable for testing and ephemeral workflows.',
  persistent: FALSE,
  supports_ttl: FALSE,
)]
class StaticMemoryBackend extends AbstractMemoryBackend {

  /**
   * The in-process store, shared across all instances in the same request.
   *
   * @var array<string, mixed>
   */
  private static array $store = [];

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    return new static($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function get(string $scope, string $scope_id, string $key, mixed $default = NULL): mixed {
    return self::$store[$this->buildStorageKey($scope, $scope_id, $key)] ?? $default;
  }

  /**
   * {@inheritdoc}
   */
  public function set(string $scope, string $scope_id, string $key, mixed $value, ?int $ttl = NULL): void {
    // TTL is not supported; silently ignored.
    self::$store[$this->buildStorageKey($scope, $scope_id, $key)] = $value;
  }

  /**
   * {@inheritdoc}
   */
  public function delete(string $scope, string $scope_id, string $key): void {
    unset(self::$store[$this->buildStorageKey($scope, $scope_id, $key)]);
  }

  /**
   * {@inheritdoc}
   */
  public function has(string $scope, string $scope_id, string $key): bool {
    return array_key_exists($this->buildStorageKey($scope, $scope_id, $key), self::$store);
  }

  /**
   * {@inheritdoc}
   */
  public function keys(string $scope, string $scope_id): array {
    $prefix = $this->buildScopePrefix($scope, $scope_id) . ':';
    $prefixLen = strlen($prefix);
    $keys = [];
    foreach (array_keys(self::$store) as $storageKey) {
      if (str_starts_with($storageKey, $prefix)) {
        $keys[] = substr($storageKey, $prefixLen);
      }
    }
    return $keys;
  }

  /**
   * {@inheritdoc}
   */
  public function clearScope(string $scope, string $scope_id): void {
    $prefix = $this->buildScopePrefix($scope, $scope_id) . ':';
    foreach (array_keys(self::$store) as $storageKey) {
      if (str_starts_with($storageKey, $prefix)) {
        unset(self::$store[$storageKey]);
      }
    }
  }

}
