<?php

/**
 * @file
 * Hooks and API documentation for the FFmpeg Media module.
 *
 * This file documents hooks provided by the FFmpeg Media module. It also
 * provides references to the plugin systems and Symfony events dispatched
 * during video conversion operations.
 *
 * @section sec_plugins Plugin Systems
 *
 * FFmpeg Media provides three plugin types for extending video processing:
 *
 * - **FFmpegCodec**: Video/audio codec plugins. Implement
 *   \Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface and use the
 *   \Drupal\ffmpeg_media\Attribute\FFmpegCodec attribute.
 *   Place plugins in Plugin/FFmpegCodec/ under your module's src/ directory.
 *
 * - **FFmpegOutput**: Output format plugins. Implement
 *   \Drupal\ffmpeg_media\Plugin\FFmpegOutput\FFmpegOutputInterface and use the
 *   \Drupal\ffmpeg_media\Attribute\FFmpegOutput attribute.
 *   Place plugins in Plugin/FFmpegOutput/ under your module's src/ directory.
 *
 * - **FFmpegProcessor**: Video processor plugins. Implement
 *   \Drupal\ffmpeg_media\Plugin\FFmpegProcessor\FFmpegProcessorInterface and
 *   use the \Drupal\ffmpeg_media\Attribute\FFmpegProcessor attribute.
 *   Place plugins in Plugin/FFmpegProcessor/ under your module's src/
 *   directory.
 *
 * @section sec_events Symfony Events
 *
 * The module dispatches events via Symfony's EventDispatcher. Subscribe to
 * these events using a tagged service (event_subscriber). Event names are
 * defined in \Drupal\ffmpeg_media\Event\FFmpegMediaEvents:
 *
 * - FFmpegMediaEvents::CONVERSION_STARTED - Fired when a video conversion
 *   begins. See \Drupal\ffmpeg_media\Event\ConversionStartedEvent.
 * - FFmpegMediaEvents::CONVERSION_PROGRESS - Fired periodically during
 *   conversion with progress data.
 *   See \Drupal\ffmpeg_media\Event\ConversionProgressEvent.
 * - FFmpegMediaEvents::CONVERSION_COMPLETED - Fired when a conversion
 *   finishes successfully.
 *   See \Drupal\ffmpeg_media\Event\ConversionCompletedEvent.
 * - FFmpegMediaEvents::CONVERSION_FAILED - Fired when a conversion fails.
 *   See \Drupal\ffmpeg_media\Event\ConversionFailedEvent.
 *
 * @section sec_supported_public_api Supported Public Extension Points
 *
 * The documented public extension API consists of:
 *
 * - The `FFmpegCodec`, `FFmpegOutput`, and `FFmpegProcessor` plugin types
 * - Their corresponding alter hooks
 * - The conversion lifecycle events in `FFmpegMediaEvents`
 * - `\Drupal\ffmpeg_media\Resolver\VideoSourceResolverInterface` for
 *   formatter integrations
 *
 * Operational services such as queue management, progress tracking, dashboard
 * helpers, and retry/backoff logic may be public for Drupal runtime reasons,
 * but they are not part of the supported contrib extension contract.
 *
 * @section sec_video_source_resolver Video Source Resolver
 *
 * The VideoSourceResolverInterface service resolves converted video
 * outputs for a media entity field. It returns a ResolvedSources value
 * object containing video sources (HLS, DASH, MP4, WebM), poster
 * image, and subtitle/caption tracks.
 *
 * Third-party formatters inject this service to serve converted outputs
 * instead of the original source file. The resolver queries the output
 * storage table and returns sources in format priority order.
 *
 * @code
 * // In your formatter's viewElements():
 * $resolver = \Drupal::service(\Drupal\ffmpeg_media\Resolver\VideoSourceResolverInterface::class);
 * $resolved = $resolver->resolveSources(
 *   mediaId: (int) $entity->id(),
 *   fieldName: $this->fieldDefinition->getName(),
 *   profileId: $this->getSetting('conversion_profile') ?: NULL,
 *   formatPriority: array_filter($this->getSetting('format_priority') ?? []),
 * );
 *
 * if ($resolved->isConverted) {
 *   // Use $resolved->sources instead of original file URL.
 *   // Optionally use $resolved->poster, $resolved->subtitles.
 * }
 * @endcode
 *
 * Third-party integration steps:
 * 1. Call VideoSourceResolver::resolveSources() in viewElements() to get
 *    converted outputs for playback.
 * 2. Optionally expose format_priority and conversion_profile settings in
 *    your formatter settings form.
 *
 * @see \Drupal\ffmpeg_media\Resolver\VideoSourceResolverInterface
 * @see \Drupal\ffmpeg_media\Resolver\ResolvedSources
 * @see \Drupal\ffmpeg_media\Event\FFmpegMediaEvents
 */

declare(strict_types=1);

/**
 * @addtogroup hooks
 * @{
 */

/**
 * Alter FFmpeg codec plugin definitions.
 *
 * Allows modules to modify the properties of codec plugins defined by other
 * modules. This hook is invoked after all codec plugin definitions have been
 * collected from the Plugin/FFmpegCodec/ namespace.
 *
 * @param array<string, array<string, mixed>> $definitions
 *   An array of codec plugin definitions, keyed by plugin ID. Each definition
 *   contains keys such as 'id', 'label', 'description', 'encoder',
 *   'supportedContainers', 'hardwareAccelerated', and 'weight'.
 *
 * @see \Drupal\ffmpeg_media\FFmpegCodecPluginManager
 * @see \Drupal\ffmpeg_media\Attribute\FFmpegCodec
 * @see \Drupal\ffmpeg_media\Plugin\FFmpegCodec\FFmpegCodecInterface
 */
function hook_ffmpeg_codec_info_alter(array &$definitions): void {
  // Change the weight of the h264 codec to make it appear first.
  if (isset($definitions['h264'])) {
    $definitions['h264']['weight'] = -10;
  }
}

/**
 * Alter FFmpeg output format plugin definitions.
 *
 * Allows modules to modify the properties of output format plugins defined by
 * other modules. This hook is invoked after all output plugin definitions have
 * been collected from the Plugin/FFmpegOutput/ namespace.
 *
 * @param array<string, array<string, mixed>> $definitions
 *   An array of output format plugin definitions, keyed by plugin ID. Each
 *   definition contains keys such as 'id', 'label', 'description',
 *   'extension', 'mimeType', 'supportedCodecs', 'defaultCodec', and 'weight'.
 *
 * @see \Drupal\ffmpeg_media\FFmpegOutputPluginManager
 * @see \Drupal\ffmpeg_media\Attribute\FFmpegOutput
 * @see \Drupal\ffmpeg_media\Plugin\FFmpegOutput\FFmpegOutputInterface
 */
function hook_ffmpeg_output_info_alter(array &$definitions): void {
  // Remove an output format that is not supported in this environment.
  unset($definitions['av1_mkv']);
}

/**
 * Alter FFmpeg processor plugin definitions.
 *
 * Allows modules to modify the properties of processor plugins defined by
 * other modules. This hook is invoked after all processor plugin definitions
 * have been collected from the Plugin/FFmpegProcessor/ namespace.
 *
 * @param array<string, array<string, mixed>> $definitions
 *   An array of processor plugin definitions, keyed by plugin ID. Each
 *   definition contains keys such as 'id', 'label', 'description',
 *   'outputType', 'outputExtension', 'requiredFilters', and 'weight'.
 *
 * @see \Drupal\ffmpeg_media\FFmpegProcessorPluginManager
 * @see \Drupal\ffmpeg_media\Attribute\FFmpegProcessor
 * @see \Drupal\ffmpeg_media\Plugin\FFmpegProcessor\FFmpegProcessorInterface
 */
function hook_ffmpeg_processor_info_alter(array &$definitions): void {
  // Override the label for a processor plugin.
  if (isset($definitions['thumbnail_generator'])) {
    $definitions['thumbnail_generator']['label'] = t(
      'Custom Thumbnail Generator',
    );
  }
}

/**
 * @} End of "addtogroup hooks".
 */
