<?php

declare(strict_types=1);

namespace Drupal\flowdrop\Service\JsonPath;

/**
 * Interface for JSONPath query service.
 *
 * Provides JSONPath (RFC 9535) querying capabilities for extracting
 * data from complex nested structures. Supports both JSONPath expressions
 * and simple property path notation for backward compatibility.
 *
 * @see https://www.rfc-editor.org/rfc/rfc9535
 *
 * @internal
 *   This class is not part of the public API and may change without notice.
 */
interface JsonPathServiceInterface {

  /**
   * Extract data from a structure using a JSONPath or property path expression.
   *
   * This method auto-detects the path type:
   * - JSONPath expressions start with "$" (e.g., "$.users[*].name")
   * - Property paths use dot or bracket notation (e.g., "users.0.name")
   *
   * @param mixed $data
   *   The data structure to query (array, object, or JSON string).
   * @param string $path
   *   The path expression (JSONPath starting with "$", or property path).
   * @param mixed $default
   *   Default value if path doesn't match anything.
   *
   * @return mixed
   *   The extracted value(s). JSONPath may return an array of matches.
   *   Property paths return a single value.
   */
  public function extract(mixed $data, string $path, mixed $default = NULL): mixed;

  /**
   * Extract a single value using JSONPath or property path.
   *
   * Unlike extract(), this always returns a single value:
   * - For JSONPath: returns first match or default
   * - For property paths: returns the value or default.
   *
   * @param mixed $data
   *   The data structure to query.
   * @param string $path
   *   The path expression.
   * @param mixed $default
   *   Default value if not found.
   *
   * @return mixed
   *   A single value or the default.
   */
  public function extractFirst(mixed $data, string $path, mixed $default = NULL): mixed;

  /**
   * Extract all matching values using JSONPath.
   *
   * @param mixed $data
   *   The data structure to query.
   * @param string $path
   *   The JSONPath expression (must start with "$").
   *
   * @return array<int, mixed>
   *   Array of all matching values. Empty array if no matches.
   */
  public function extractAll(mixed $data, string $path): array;

  /**
   * Check if a path matches any values in the data.
   *
   * @param mixed $data
   *   The data structure to query.
   * @param string $path
   *   The path expression.
   *
   * @return bool
   *   TRUE if the path matches at least one value.
   */
  public function exists(mixed $data, string $path): bool;

  /**
   * Apply multiple path mappings to extract data.
   *
   * Useful for trigger data mapping where multiple fields need extraction.
   *
   * @param mixed $sourceData
   *   The source data structure.
   * @param array<string, string> $mappings
   *   Associative array where keys are output field names and
   *   values are path expressions.
   *
   * @return array<string, mixed>
   *   Extracted data with keys matching the mapping keys.
   */
  public function applyMappings(mixed $sourceData, array $mappings): array;

  /**
   * Check if a string is a JSONPath expression.
   *
   * @param string $path
   *   The path string to check.
   *
   * @return bool
   *   TRUE if the path is a JSONPath expression (starts with "$").
   */
  public function isJsonPath(string $path): bool;

  /**
   * Validate a JSONPath expression syntax.
   *
   * @param string $path
   *   The JSONPath expression to validate.
   *
   * @return bool
   *   TRUE if the expression is syntactically valid.
   */
  public function isValidJsonPath(string $path): bool;

}
