<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Service;

use Drupal\file\FileInterface;
use Drupal\media\MediaInterface;

/**
 * Interface for managing file operations during video conversion.
 *
 * Handles file entity creation, path resolution, temp file cleanup,
 * and file usage tracking.
 *
 * @internal Runtime service, not part of the supported contrib extension API.
 */
interface ConversionFileManagerInterface {

  /**
   * Creates a file entity for a converted output.
   *
   * @param string $path
   *   Local filesystem path to the file.
   * @param string $mimeType
   *   MIME type of the file.
   *
   * @return \Drupal\file\FileInterface
   *   Created file entity.
   */
  public function createFileEntity(
    string $path,
    string $mimeType,
  ): FileInterface;

  /**
   * Generates an output path in a specific directory.
   *
   * The media ID is used as a subdirectory to prevent path collisions
   * when multiple media entities share the same source filename. When
   * a field name is provided, it is inserted as an additional path segment
   * to isolate outputs from different fields on the same media entity.
   *
   * @param string $sourcePath
   *   Source file path.
   * @param string $outputDirectory
   *   Target output directory (may be stream URI).
   * @param string $extension
   *   File extension.
   * @param int $mediaId
   *   Media entity ID, used as subdirectory for collision-safe paths.
   * @param string $codecSuffix
   *   Optional codec suffix appended before extension (e.g., 'hevc'
   *   produces '*_converted_hevc.mp4'). Used to differentiate multiple
   *   outputs with the same container.
   * @param string $fieldName
   *   Source field name. When non-empty, inserted between media ID and
   *   filename to prevent cross-field collisions on multi-field entities.
   *
   * @return string
   *   Generated output path.
   */
  #[\NoDiscard]
  public function generateOutputPathInDirectory(
    string $sourcePath,
    string $outputDirectory,
    string $extension,
    int $mediaId,
    string $codecSuffix = '',
    string $fieldName = '',
  ): string;

  /**
   * Resolves a storage URI from a filesystem path.
   *
   * Converts absolute paths to Drupal stream URIs when possible.
   *
   * @param string $path
   *   Filesystem path or stream URI.
   *
   * @return string
   *   Stream URI (e.g., public://...) or original path.
   */
  #[\NoDiscard]
  public function getStorageUri(string $path): string;

  /**
   * Resolves a local filesystem path from a stream URI.
   *
   * @param string $path
   *   Stream URI or filesystem path.
   *
   * @return string
   *   Local filesystem path.
   *
   * @throws \RuntimeException
   *   If the stream URI cannot be resolved to a local path.
   */
  #[\NoDiscard]
  public function getLocalPath(string $path): string;

  /**
   * Cleans up temporary files.
   *
   * @param array<string> $tempFiles
   *   Array of temporary file paths to delete.
   */
  public function cleanupTempFiles(array $tempFiles): void;

  /**
   * Checks if a file has usage from entities other than the given media.
   *
   * @param \Drupal\file\FileInterface $file
   *   File entity.
   * @param \Drupal\media\MediaInterface|null $media
   *   Media entity to exclude from usage check, or NULL.
   *
   * @return bool
   *   TRUE if other entities reference this file.
   */
  #[\NoDiscard]
  public function hasOtherFileUsage(
    FileInterface $file,
    ?MediaInterface $media,
  ): bool;

  /**
   * Counts total usage of a file across all entities.
   *
   * @param \Drupal\file\FileInterface $file
   *   File entity.
   *
   * @return int
   *   Total usage count.
   */
  #[\NoDiscard]
  public function countFileUsage(FileInterface $file): int;

  /**
   * Checks if a media entity references a file in a specific field.
   *
   * @param \Drupal\media\MediaInterface $media
   *   Media entity.
   * @param string $fieldName
   *   Field name to check.
   * @param \Drupal\file\FileInterface $file
   *   File to look for.
   *
   * @return bool
   *   TRUE if the media references the file.
   */
  #[\NoDiscard]
  public function mediaReferencesFile(
    MediaInterface $media,
    string $fieldName,
    FileInterface $file,
  ): bool;

}
