# Post processing that we can do after a post has already been cooked. For
# example, inserting the onebox content, or image sizes.

require_dependency 'oneboxer'

class CookedPostProcessor

  def initialize(post, opts={})
    @dirty = false
    @opts = opts
    @post = post
    @doc = Hpricot(post.cooked)
  end

  def dirty?
    @dirty
  end

  # Bake onebox content into the post
  def post_process_oneboxes    
    args = {post_id: @post.id}
    args[:invalidate_oneboxes] = true if @opts[:invalidate_oneboxes]

    Oneboxer.each_onebox_link(@doc) do |url, element|
      onebox = Oneboxer.onebox(url, args)
      if onebox
        element.swap onebox 
        @dirty = true
      end
    end    
  end

  # First let's consider the images       
  def post_process_images    
    images = @doc.search("img")
    if images.present?

      # Extract the first image from the first post and use it as the 'topic image'
      if @post.post_number == 1
        img = images.first
        @post.topic.update_column :image_url, img['src'] if img['src'].present?
      end

      images.each do |img|
        if img['src'].present?

          # If we provided some image sizes, look those up first
          if @opts[:image_sizes].present?
            if dim = @opts[:image_sizes][img['src']]
              w, h = ImageSizer.resize(dim['width'], dim['height'])
              img.set_attribute 'width', w.to_s
              img.set_attribute 'height', h.to_s
              @dirty = true
            end
          end

          # If the image has no width or height, figure them out.
          if img['width'].blank? or img['height'].blank?               
            dim = CookedPostProcessor.image_dimensions(img['src'])
            if dim.present?
              img.set_attribute 'width', dim[0].to_s
              img.set_attribute 'height', dim[1].to_s
              @dirty = true
            end
          end

        end
      end
    end      
  end


  def post_process
    return unless @doc.present?
    post_process_images
    post_process_oneboxes
  end

  def html
    @doc.try(:to_html)
  end

  # Retrieve the image dimensions for a url
  def self.image_dimensions(url)
    return nil unless SiteSetting.crawl_images?
    uri = URI.parse(url)
    return nil unless %w(http https).include?(uri.scheme)
    w, h = FastImage.size(url)

    ImageSizer.resize(w, h)
  end

end