using System.Text;
using ErsatzTV.Core.Images;
using NUnit.Framework;
using Shouldly;
using SkiaSharp;

namespace ErsatzTV.Core.Tests.Images;

[TestFixture]
public class ImageContentTypesTests
{
    [TestCase(SKEncodedImageFormat.Png, "image/png")]
    [TestCase(SKEncodedImageFormat.Jpeg, "image/jpeg")]
    [TestCase(SKEncodedImageFormat.Webp, "image/webp")]
    public void DetectContentType_Should_Sniff_Real_Image_Bytes(SKEncodedImageFormat format, string expected)
    {
        byte[] bytes = EncodeTinyImage(format);

        Option<string> detected = ImageContentTypes.DetectContentType(bytes);

        detected.IfNone(string.Empty).ShouldBe(expected);
    }

    [Test]
    public void DetectContentType_Should_Reject_Non_Image_Payload()
    {
        // The stored-XSS payload from issue #283 — script bytes that a spoofed content type would
        // otherwise have let through.
        byte[] html = Encoding.UTF8.GetBytes("<script>alert(document.domain)</script>");

        ImageContentTypes.DetectContentType(html).IsNone.ShouldBeTrue();
    }

    [Test]
    public void DetectContentType_Should_Return_None_For_Empty_Or_Null()
    {
        ImageContentTypes.DetectContentType([]).IsNone.ShouldBeTrue();
        ImageContentTypes.DetectContentType(null).IsNone.ShouldBeTrue();
    }

    [TestCase("image/png", true)]
    [TestCase("image/jpeg", true)]
    [TestCase("image/gif", true)]
    [TestCase("image/webp", true)]
    [TestCase("IMAGE/PNG", true)]
    [TestCase("text/html", false)]
    [TestCase("image/svg+xml", false)]
    [TestCase("", false)]
    [TestCase(null, false)]
    public void IsAccepted_Should_Allow_Only_Raster_Image_Types(string contentType, bool expected) =>
        ImageContentTypes.IsAccepted(contentType).ShouldBe(expected);

    private static byte[] EncodeTinyImage(SKEncodedImageFormat format)
    {
        using var bitmap = new SKBitmap(2, 2);
        using SKImage image = SKImage.FromBitmap(bitmap);
        using SKData data = image.Encode(format, 100);
        return data.ToArray();
    }
}
