<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Service;

use Drupal\ffmpeg_media\Enum\HardwareType;
use Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface;
use Drupal\ffmpeg_media\ValueObject\ConversionOptions;

/**
 * Interface for managing hardware-accelerated encoding.
 *
 * Centralizes encoder selection, hardware pipeline construction,
 * and hardware detection logic.
 *
 * @internal Runtime service, not part of the supported contrib extension API.
 */
interface HardwareAccelerationManagerInterface {

  /**
   * Selects the best encoder for a codec based on hardware configuration.
   *
   * @param \Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface $codecPlugin
   *   The codec plugin instance.
   * @param string $codecId
   *   The codec identifier (e.g., 'h264', 'hevc', 'av1').
   *
   * @return array{encoder: string|null, hwType: \Drupal\ffmpeg_media\Enum\HardwareType|null}
   *   The selected encoder name (or NULL for codec default) and the
   *   hardware type for circuit breaker tracking.
   */
  #[\NoDiscard]
  public function selectEncoder(
    FFmpegCodecInterface $codecPlugin,
    string $codecId,
  ): array;

  /**
   * Builds a hardware pipeline for GPU-accelerated encoding.
   *
   * @param string $codec
   *   Target codec (h264, hevc, av1, vp9).
   * @param \Drupal\ffmpeg_media\ValueObject\ConversionOptions $options
   *   Conversion options.
   *
   * @return array{init_args: array<string>, decode_args: array<string>, filter_complex: string|null, encode_args: array<string>, encoder: string|null}|null
   *   Pipeline array or NULL if unavailable or disabled.
   */
  public function buildHardwarePipeline(
    string $codec,
    ConversionOptions $options,
  ): ?array;

  /**
   * Extracts hardware type from a pipeline's encoder.
   *
   * @param array{init_args: array<string>, decode_args: array<string>, filter_complex: string|null, encode_args: array<string>, encoder: string|null} $pipeline
   *   Hardware pipeline array.
   *
   * @return \Drupal\ffmpeg_media\Enum\HardwareType|null
   *   Hardware type or NULL.
   */
  #[\NoDiscard]
  public function extractHwTypeFromPipeline(array $pipeline): ?HardwareType;

  /**
   * Detects the best available hardware acceleration type.
   *
   * @return string|null
   *   Hardware type string value or NULL if none available.
   */
  #[\NoDiscard]
  public function detectBestHardware(): ?string;

  /**
   * Overrides the video encoder in codec arguments.
   *
   * @param array<int, string> $args
   *   Array of FFmpeg arguments from codec plugin.
   * @param string $encoder
   *   Hardware encoder to use.
   *
   * @return array<int, string>
   *   Modified arguments with replaced encoder.
   */
  #[\NoDiscard]
  public function overrideEncoder(array $args, string $encoder): array;

  /**
   * Clears the in-memory encoder availability cache.
   *
   * Call this when encoder availability may have changed, such as after
   * a force-refresh of hardware capabilities.
   */
  public function clearEncoderCache(): void;

  /**
   * Pre-warms the encoder availability cache.
   *
   * Queries FFmpeg for all known hardware encoders and persists the
   * results to the Drupal cache backend. This eliminates the cold-start
   * cost on the first conversion request after a cache miss.
   *
   * Typically called from hook_install() so the cache is populated
   * immediately on module installation.
   *
   * @return int
   *   Number of available encoders found and cached.
   */
  public function warmEncoderCache(): int;

}
