using ErsatzTV.FFmpeg.Capabilities;
using ErsatzTV.FFmpeg.GlobalOption.HardwareAcceleration;
using NUnit.Framework;
using Shouldly;
using static LanguageExt.Prelude;

namespace ErsatzTV.FFmpeg.Tests.GlobalOption.HardwareAcceleration;

[TestFixture]
public class QsvHardwareAccelerationOptionTests
{
    [Test]
    public void GlobalOptions_WithDevice_ShouldDeriveQsvDeviceFromVaapiDevice()
    {
        var option = new QsvHardwareAccelerationOption("/dev/dri/renderD128", FFmpegCapability.Software);

        option.GlobalOptions.ShouldBe(
        [
            "-init_hw_device", "vaapi=va:/dev/dri/renderD128",
            "-init_hw_device", "qsv=hw@va",
            "-filter_hw_device", "hw"
        ]);
    }

    [Test]
    public void GlobalOptions_WithHardwareDecode_ShouldEnableQsvHwaccel()
    {
        var option = new QsvHardwareAccelerationOption(None, FFmpegCapability.Hardware);

        option.GlobalOptions.ShouldBe(
        [
            "-hwaccel", "qsv",
            "-hwaccel_output_format", "qsv",
            "-init_hw_device", "qsv=hw",
            "-filter_hw_device", "hw"
        ]);
    }

    [Test]
    public void GlobalOptions_WithHardwareDecode_AndPreferNative_ShouldUseVaapiDecodeToSoftware()
    {
        var option = new QsvHardwareAccelerationOption("/dev/dri/renderD128", FFmpegCapability.Hardware, preferNativeDecoder: true);

        option.GlobalOptions.ShouldBe(
        [
            "-hwaccel", "vaapi",
            "-init_hw_device", "vaapi=va:/dev/dri/renderD128",
            "-init_hw_device", "qsv=hw@va",
            "-filter_hw_device", "hw"
        ]);
        // must NOT keep frames on the GPU as VA-API surfaces
        option.GlobalOptions.ShouldNotContain("-hwaccel_output_format");
    }
}
