class PostThumbnailUploadValidator
  MAX_THUMBNAIL_BYTES = 20 * 1024 * 1024
  ALLOWED_CONTENT_TYPES = Preview::ThumbnailFetcher::RASTER_IMAGE_CONTENT_TYPES.freeze

  class InvalidUpload < StandardError; end

  def self.validate! thumbnail
    return if thumbnail.blank?
    unless thumbnail.is_a?(ActionDispatch::Http::UploadedFile)
      raise InvalidUpload, 'thumbnail upload が不正です．'
    end
    raise InvalidUpload, 'thumbnail file size が大きすぎます．' if thumbnail.size > MAX_THUMBNAIL_BYTES
    raise InvalidUpload, 'サムネイル画像の形式が不正です．' unless allowed_content_type?(thumbnail.content_type)
    bytes = thumbnail.read
    raise InvalidUpload, 'サムネイル画像の形式が不正です．' if Post.svg_document_bytes?(bytes)
    unless Post.raster_thumbnail_bytes?(bytes)
      raise InvalidUpload, 'サムネイル画像の形式が不正です．'
    end

    attachment = Post.resized_thumbnail_attachment(
        StringIO.new(bytes),
        content_type: thumbnail.content_type)
    attachment[:io].close if attachment[:io].respond_to?(:close)
  rescue MiniMagick::Error, Timeout::Error
    raise InvalidUpload, 'サムネイル画像の変換に失敗しました．'
  ensure
    thumbnail&.rewind if thumbnail.respond_to?(:rewind)
  end

  def self.allowed_content_type? content_type
    mime_type = content_type.to_s.split(';', 2).first.to_s.downcase.strip
    ALLOWED_CONTENT_TYPES.include?(mime_type)
  end
end
