<?php

declare(strict_types=1);

namespace Drupal\flowdrop\DTO;

/**
 * Interface for parameter bags.
 *
 * A ParameterBag contains resolved parameter values for node execution.
 * All parameters are pre-resolved and validated before being passed to
 * the plugin's process() method.
 *
 * This is the Unified Parameter System that provides a single, unified
 * approach to handling both runtime inputs and configuration values.
 *
 * @see \Drupal\flowdrop\DTO\ParameterBag
 * @see docs/development/unified-parameter-system-spec.md
 *
 * @api
 */
interface ParameterBagInterface {

  /**
   * Get a parameter value.
   *
   * @param string $name
   *   The parameter name.
   * @param mixed $default
   *   Default value if parameter doesn't exist.
   *
   * @return mixed
   *   The parameter value.
   */
  public function get(string $name, mixed $default = NULL): mixed;

  /**
   * Check if a parameter exists.
   *
   * Note: This follows Symfony's ParameterBag semantics - it only checks
   * for key existence, not whether the value is null. Use get() with a
   * default to handle null values.
   *
   * @param string $name
   *   The parameter name.
   *
   * @return bool
   *   TRUE if parameter key exists (value may be null).
   */
  public function has(string $name): bool;

  /**
   * Get all parameters as an associative array.
   *
   * @return array<string, mixed>
   *   All parameter values.
   */
  public function all(): array;

  /**
   * Get all parameter names.
   *
   * @return array<string>
   *   Parameter names.
   */
  public function keys(): array;

  /**
   * Check if the bag is empty.
   *
   * @return bool
   *   TRUE if no parameters.
   */
  public function isEmpty(): bool;

  /**
   * Get a typed parameter value.
   *
   * @param string $name
   *   The parameter name.
   * @param string $type
   *   Expected type ('string', 'int', 'float', 'bool', 'array').
   * @param mixed $default
   *   Default value.
   *
   * @return mixed
   *   The typed value.
   *
   * @throws \InvalidArgumentException
   *   If type doesn't match.
   */
  public function getTyped(string $name, string $type, mixed $default = NULL): mixed;

  /**
   * Get a string parameter.
   *
   * @param string $name
   *   The parameter name.
   * @param string $default
   *   Default value.
   *
   * @return string
   *   The string value.
   */
  public function getString(string $name, string $default = ""): string;

  /**
   * Get an integer parameter.
   *
   * @param string $name
   *   The parameter name.
   * @param int $default
   *   Default value.
   *
   * @return int
   *   The integer value.
   */
  public function getInt(string $name, int $default = 0): int;

  /**
   * Get a float parameter.
   *
   * @param string $name
   *   The parameter name.
   * @param float $default
   *   Default value.
   *
   * @return float
   *   The float value.
   */
  public function getFloat(string $name, float $default = 0.0): float;

  /**
   * Get a boolean parameter.
   *
   * @param string $name
   *   The parameter name.
   * @param bool $default
   *   Default value.
   *
   * @return bool
   *   The boolean value.
   */
  public function getBool(string $name, bool $default = FALSE): bool;

  /**
   * Get an array parameter.
   *
   * @param string $name
   *   The parameter name.
   * @param array<mixed> $default
   *   Default value.
   *
   * @return array<mixed>
   *   The array value.
   */
  public function getArray(string $name, array $default = []): array;

}
