require "image_sorcery"

module Jobs

  class GenerateAvatars < Jobs::Base

    def execute(args)
      raise Discourse::ImageMagickMissing.new unless system("command -v convert >/dev/null;")

      upload_id, user_id = args[:upload_id], args[:user_id]
      raise Discourse::InvalidParameters.new(:upload_id) if upload_id.blank?
      raise Discourse::InvalidParameters.new(:user_id) if user_id.blank?

      upload = Upload.where(id: upload_id).first
      user = User.where(id: user_id).first
      return if upload.nil? || user.nil?

      external_copy = Discourse.store.download(upload) if Discourse.store.external?
      original_path = if Discourse.store.external?
        external_copy.path
      else
        Discourse.store.path_for(upload)
      end

      source = original_path
      # extract the first frame when it's a gif
      source << "[0]" unless SiteSetting.allow_animated_avatars
      image = ImageSorcery.new(source)
      extension = File.extname(original_path)

      [120, 45, 32, 25, 20].each do |s|
        # handle retina too
        [s, s * 2].each do |size|
          begin
            # create a temp file with the same extension as the original
            temp_file = Tempfile.new(["discourse-avatar", extension])
            # create a transparent centered square thumbnail
            if image.convert(temp_file.path,
                             gravity: "center",
                             thumbnail: "#{size}x#{size}^",
                             extent: "#{size}x#{size}",
                             background: "transparent")
              if Discourse.store.store_avatar(temp_file, upload, size).blank?
                Rails.logger.error("Failed to store avatar #{size} for #{upload.url} from #{source}")
              end
            else
              Rails.logger.error("Failed to create avatar #{size} for #{upload.url} from #{source}")
            end
          ensure
            # close && remove temp file
            temp_file && temp_file.close!
          end
        end
      end

      # make sure we remove the cached copy from external stores
      external_copy.close! if Discourse.store.external?

      # attach the avatar to the user
      user.uploaded_avatar_template = Discourse.store.avatar_template(upload)
      user.save!

    end

  end

end
