using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Images;
using ErsatzTV.Core.Interfaces.Streaming;
using LanguageExt;

namespace ErsatzTV.Infrastructure.Images;

public class RemoteLogoCacher(
    IRemoteImageFetcher fetcher,
    IRemoteImageValidator validator,
    IImageCache imageCache) : IRemoteLogoCacher
{
    public async Task<Either<BaseError, string>> CacheFromUrl(Uri uri, CancellationToken cancellationToken)
    {
        try
        {
            await using Stream stream = await fetcher.Fetch(uri, cancellationToken);

            // validate by decoding under the budget (throws if unsafe); we cache the raw bytes
            await validator.Validate(stream, uri, cancellationToken);

            stream.Position = 0;
            return await imageCache.SaveArtworkToCache(stream, ArtworkKind.Logo);
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            throw;
        }
        catch (Exception ex)
        {
            return BaseError.New($"Could not download logo from {uri}: {ex.Message}");
        }
    }
}
