# typed: strict
# frozen_string_literal: true

class LoadedMedia
  extend T::Sig
  extend T::Helpers
  abstract!

  sig do
    params(content_type: String, media_path: String).returns(
      T.nilable(LoadedMedia),
    )
  end
  def self.from_file(content_type, media_path)
    case content_type
    when %r{image/gif}
      VipsUtil.try_load_gif(
        media_path,
        load_gif: -> { LoadedMedia::Gif.new(media_path) },
        on_load_failed: ->(detected_content_type) do
          return from_file(detected_content_type, media_path)
        end,
      )
    when %r{image/jpeg}, %r{image/jpg}, %r{image/png}, %r{image/bmp}
      LoadedMedia::StaticImage.new(media_path)
    when %r{video/webm}
      LoadedMedia::Webm.new(media_path)
    else
      return nil
    end
  end

  sig { abstract.returns(Integer) }
  def num_frames
  end

  sig do
    abstract
      .params(frame: Integer, path: String, options: ThumbnailOptions)
      .void
  end
  def write_frame_thumbnail(frame, path, options)
  end

  protected

  sig(:final) do
    params(image: Vips::Image, path: String, options: ThumbnailOptions).void
  end
  def write_image_thumbnail(image, path, options)
    FileUtils.mkdir_p(File.dirname(path))
    tmp_path =
      File.join(BlobFile::TMP_DIR, "thumbnail-#{SecureRandom.uuid}.jpg")
    image.thumbnail_image(
      options.width,
      height: options.height,
      size: options.size,
    ).jpegsave(tmp_path, interlace: options.interlace, Q: options.quality)
    FileUtils.mv(tmp_path, path)
  ensure
    File.delete(tmp_path) if tmp_path && File.exist?(tmp_path)
  end
end
