<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Service;

use Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface;
use Drupal\ffmpeg_media\Plugin\FFmpegOutput\FFmpegOutputInterface;
use Drupal\ffmpeg_media\ValueObject\ConversionOptions;
use Drupal\ffmpeg_media\ValueObject\VideoInfo;

/**
 * Builds FFmpeg command arrays for single-output and adaptive conversions.
 *
 * @internal Runtime service, not part of the supported contrib extension API.
 */
interface FfmpegCommandBuilderInterface {

  /**
   * Builds the complete output command array for a single-output conversion.
   *
   * @param string $inputPath
   *   Input file path.
   * @param string $outputPath
   *   Output file path.
   * @param \Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface $codec
   *   Codec plugin.
   * @param \Drupal\ffmpeg_media\Plugin\FFmpegOutput\FFmpegOutputInterface $outputPlugin
   *   Output plugin.
   * @param \Drupal\ffmpeg_media\ValueObject\ConversionOptions $options
   *   Conversion options.
   * @param \Drupal\ffmpeg_media\ValueObject\VideoInfo|null $videoInfo
   *   Video information for hardware detection.
   * @param bool $softwareOnly
   *   If TRUE, skip all hardware acceleration.
   *
   * @return array{command: array<string>, hwType: \Drupal\ffmpeg_media\Enum\HardwareType|null}
   *   Command array and resolved hardware type.
   */
  #[\NoDiscard]
  public function buildOutputCommand(
    string $inputPath,
    string $outputPath,
    FFmpegCodecInterface $codec,
    FFmpegOutputInterface $outputPlugin,
    ConversionOptions $options,
    ?VideoInfo $videoInfo,
    bool $softwareOnly = FALSE,
  ): array;

  /**
   * Builds command array for adaptive streaming output (HLS/DASH).
   *
   * @param string $inputPath
   *   Input file path.
   * @param string $outputPath
   *   Output file path (manifest path).
   * @param \Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface $codec
   *   Codec plugin.
   * @param array<string> $adaptiveArgs
   *   Adaptive streaming arguments from output plugin.
   * @param \Drupal\ffmpeg_media\ValueObject\ConversionOptions $options
   *   Conversion options.
   * @param \Drupal\ffmpeg_media\ValueObject\VideoInfo|null $videoInfo
   *   Video information.
   * @param array<string> $extraInputArgs
   *   Additional input arguments (e.g., subtitle -i inputs).
   *
   * @return array{command: array<string>, hwType: \Drupal\ffmpeg_media\Enum\HardwareType|null}
   *   Command array and resolved hardware type.
   */
  #[\NoDiscard]
  public function buildAdaptiveCommand(
    string $inputPath,
    string $outputPath,
    FFmpegCodecInterface $codec,
    array $adaptiveArgs,
    ConversionOptions $options,
    ?VideoInfo $videoInfo,
    array $extraInputArgs = [],
  ): array;

  /**
   * Strips -vf and -filter:v arguments from a command array.
   *
   * Used for adaptive streaming where -filter_complex handles scaling.
   *
   * @param array<int, string> $args
   *   FFmpeg arguments.
   *
   * @return array<int, string>
   *   Arguments with -vf/-filter:v entries removed.
   */
  #[\NoDiscard]
  public function stripVideoFilters(array $args): array;

  /**
   * Validates a file path for safety before passing to FFmpeg.
   *
   * Rejects paths containing traversal sequences (../, ..\), null bytes,
   * or disallowed stream wrappers. Paths must use allowed stream wrappers
   * (public://, private://, temporary://) or be absolute filesystem paths
   * (starting with / on Unix, drive letter on Windows). Relative paths
   * are rejected.
   *
   * @param string $path
   *   The file path to validate.
   *
   * @throws \Drupal\ffmpeg_media\Exception\PathTraversalException
   *   If the path fails validation.
   */
  public function validatePath(string $path): void;

}
