// Webcam capture pipeline, quality selection, and launcher preview tap support.
use anyhow::Context;
use gst::prelude::*;
use gstreamer as gst;
use gstreamer_app as gst_app;
use lesavka_common::lesavka::VideoPacket;
use std::{
    io::{Read, Write},
    os::fd::IntoRawFd,
    path::{Path, PathBuf},
    process::{Child, Command, Stdio},
    sync::{
        Arc,
        atomic::{AtomicBool, Ordering},
    },
    thread,
    time::Duration,
};

const CAMERA_PREVIEW_TAP_ENV: &str = "LESAVKA_UPLINK_CAMERA_PREVIEW";

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum CameraSourceProfile {
    Raw,
    Mjpeg,
    AutoDecode,
}

fn env_u32(name: &str, default: u32) -> u32 {
    std::env::var(name)
        .ok()
        .and_then(|v| v.parse::<u32>().ok())
        .unwrap_or(default)
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CameraCodec {
    H264,
    Hevc,
    Mjpeg,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CameraConfig {
    pub codec: CameraCodec,
    pub width: u32,
    pub height: u32,
    pub fps: u32,
}

pub struct CameraCapture {
    #[allow(dead_code)] // kept alive to hold PLAYING state
    pipeline: gst::Pipeline,
    sink: gst_app::AppSink,
    ffmpeg_child: Option<Child>,
    preview_tap_running: Option<Arc<AtomicBool>>,
    pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser,
    frame_duration_us: u64,
}

include!("camera/capture_pipeline.rs");
include!("camera/ffmpeg_hevc_capture.rs");
include!("camera/device_selection.rs");
include!("camera/encoder_selection.rs");

include!("camera/source_description.rs");
include!("camera/preview_tap.rs");
include!("camera/bus_and_encoder.rs");

#[cfg(test)]
#[path = "camera/tests/mod.rs"]
mod tests;
