import type { Size } from '../common-types/Size';
import type { VideoCodec } from '../common-types/VideoCodec';
import type { Location } from '../location/Location.nitro';
import type { CameraOutput } from './CameraOutput.nitro';
import type { Recorder } from './Recorder.nitro';
/**
 * Configuration options for a {@linkcode CameraVideoOutput}.
 *
 * @see {@linkcode CameraVideoOutput}
 * @see {@linkcode useVideoOutput | useVideoOutput(...)}
 */
export interface VideoOutputOptions {
    /**
     * The target Video Resolution to use.
     *
     * @discussion
     * The {@linkcode CameraSession} will negotiate all
     * output {@linkcode targetResolution}s and constraints (such
     * as HDR, FPS, etc) in a {@linkcode CameraSessionConfig} to
     * finalize the Resolution used for the Output.
     * This is therefore merely a resolution _target_, and may
     * not be exactly met.
     *
     * If the given {@linkcode targetResolution} cannot be met
     * exactly, its aspect ratio (computed by
     * {@linkcode Size.width} / {@linkcode Size.height}) will
     * be prioritized over pixel count.
     */
    targetResolution: Size;
    /**
     * Whether to enable, or disable audio in video
     * recordings.
     * By default, no audio is recorded.
     *
     * This requires audio/microphone permission.
     *
     * @default false
     */
    enableAudio?: boolean;
    /**
     * If set to `true`, the {@linkcode CameraVideoOutput}
     * will be persistent.
     *
     * A persistent {@linkcode CameraVideoOutput} can continue
     * to record even while switching Cameras.
     *
     * This may require additional processing power,
     * or choose a different (non-fully-native) path
     * for recording, so it is disabled by default.
     *
     * - On iOS, enabling {@linkcode enablePersistentRecorder}
     *   will use a custom [`AVCaptureVideoDataOutput`](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutput) +
     *   `AVAssetWriter` pipeline instead of the fully internal [`AVCaptureMovieFileOutput`](https://developer.apple.com/documentation/avfoundation/avcapturemoviefileoutput).
     * - On Android, enabling {@linkcode enablePersistentRecorder}
     *   will use [`asPersistentRecording()`](https://developer.android.com/reference/androidx/camera/video/PendingRecording#asPersistentRecording()).
     *
     * @default false
     */
    enablePersistentRecorder?: boolean;
    /**
     * If set to `true`, the {@linkcode CameraVideoOutput}
     * supports using higher resolution (and potentially
     * also higher bit-rate and higher frame rate) media codecs
     * to encode video frames to the video container.
     *
     * On Android, this binds to [`VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE`](https://developer.android.com/reference/kotlin/androidx/camera/video/Recorder#VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE())
     * if `true`, and [`VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE`](https://developer.android.com/reference/kotlin/androidx/camera/video/Recorder#VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE())
     * if set to `false`.
     *
     * In practice, enabling this allows using formats with higher
     * video resolutions, at the risk of higher power usage.
     *
     * As codecs are very device-specific, enabling this may cause
     * instability issues, so use this with caution.
     *
     * @platform Android
     * @default false
     */
    enableHigherResolutionCodecs?: boolean;
    /**
     * Specifies the target bit-rate for the
     * {@linkcode CameraVideoOutput}, in bits per second.
     *
     * The encoder may or may not encode with exactly this bit-rate,
     * depending on system pressure, moving pixels, and file size
     * constraints - but it will be taken as reference.
     *
     * @default undefined
     */
    targetBitRate?: number;
    /**
     * The container file type for recordings produced by this output.
     *
     * On Android this is always `.mp4` and this field is ignored.
     *
     * @platform iOS
     * @default 'mov'
     */
    fileType?: RecorderFileType;
}
/**
 * Container file type for a {@linkcode CameraVideoOutput}'s recordings.
 */
export type RecorderFileType = 'mp4' | 'mov';
/**
 * Output settings for a {@linkcode CameraVideoOutput}.
 *
 * @see {@linkcode CameraVideoOutput}
 * @see {@linkcode CameraVideoOutput.setOutputSettings | CameraVideoOutput.setOutputSettings(...)}
 */
export interface VideoOutputSettings {
    /**
     * Configures the {@linkcode VideoCodec} to use for recording a video.
     * By default, it is `undefined`, and the most efficient codec will
     * be selected (likely {@linkcode VideoCodec | h265})
     */
    codec?: VideoCodec;
}
/**
 * Video Recorder settings for a {@linkcode Recorder}
 * created by a {@linkcode CameraVideoOutput}.
 *
 * @see {@linkcode CameraVideoOutput}
 * @see {@linkcode Recorder}
 * @see {@linkcode CameraVideoOutput.createRecorder | CameraVideoOutput.createRecorder(...)}
 */
export interface RecorderSettings {
    /**
     * Sets the given {@linkcode Location} to be embedded
     * into the video metadata using the ISO-6709 standard.
     */
    location?: Location;
    /**
     * The absolute path (including file name and extension) where
     * the recording file should be written to, or `undefined` to
     * create a file in the device's temporary directory.
     * Pass a filesystem path, not a `file://` URL.
     *
     * All parent directories in this {@linkcode filePath} will
     * be automatically created if they do not yet exist.
     *
     * @default undefined
     */
    filePath?: string;
    /**
     * If set, the recording automatically stops once it reaches
     * this duration, in seconds.
     *
     * When the limit is reached, the recording is finalized
     * successfully, and the `onRecordingFinished` callback
     * passed to {@linkcode Recorder.startRecording | startRecording(...)}
     * is invoked with the resulting file path — the same
     * behavior as calling {@linkcode Recorder.stopRecording | stopRecording()}.
     *
     * @default undefined
     */
    maxDuration?: number;
    /**
     * If set, the recording automatically stops once the file
     * reaches this size, in bytes.
     *
     * When the limit is reached, the recording is finalized
     * successfully, and the `onRecordingFinished` callback
     * passed to {@linkcode Recorder.startRecording | startRecording(...)}
     * is invoked with the resulting file path — the same
     * behavior as calling {@linkcode Recorder.stopRecording | stopRecording()}.
     *
     * @default undefined
     */
    maxFileSize?: number;
}
/**
 * A Video output allows recording videos (possibly with audio)
 * to a file.
 *
 * @see {@linkcode VideoOutputOptions}
 * @see {@linkcode Recorder}
 * @see {@linkcode useVideoOutput | useVideoOutput(...)}
 * @example
 * Creating a `CameraVideoOutput` via the Hooks API:
 * ```ts
 * const videoOutput = useVideoOutput()
 * ```
 *
 * @example
 * Creating a `CameraVideoOutput` via the Imperative API:
 * ```ts
 * const videoOutput = VisionCamera.createVideoOutput({
 *   targetResolution: CommonResolutions.FHD_16_9,
 * })
 * ```
 */
export interface CameraVideoOutput extends CameraOutput {
    /**
     * Get all supported {@linkcode VideoCodec | VideoCodecs} this
     * {@linkcode CameraVideoOutput} currently can record in.
     *
     * This method must be called after the {@linkcode CameraVideoOutput}
     * has been attached to a Camera Session.
     *
     * @platform iOS
     * @throws This method throws if you call it before this output
     * is attached to a Camera Session (via `configure(...)`)
     */
    getSupportedVideoCodecs(): VideoCodec[];
    /**
     * Set the output settings for this video output.
     * This method must be called after the output has been
     * attached to the Camera Session, and before
     * {@linkcode createRecorder | createRecorder(...)}.
     *
     * @platform iOS
     */
    setOutputSettings(settings: VideoOutputSettings): Promise<void>;
    /**
     * Creates and prepares a new {@linkcode Recorder}
     * instance with the given {@linkcode RecorderSettings}.
     *
     * The {@linkcode Recorder} will record to the configured
     * file path, or to a temporary file if no path was provided.
     * The {@linkcode Recorder}'s file paths are filesystem paths,
     * not `file://` URLs.
     * It can only record once.
     *
     * If you want to create a second recording,
     * you must create a new {@linkcode Recorder}.
     */
    createRecorder(settings: RecorderSettings): Promise<Recorder>;
}
