require 'timeout'
require 'uri'

class UrlActiveValidator < ActiveModel::EachValidator

  # Checks the status of the webpage at the given url
  # To speed things up we ONLY request the head and not the entire page.
  # Bypass check for fanfiction.net and ficbook.net because of ip block
  def validate_each(record,attribute,value)
    return true if value.match("fanfiction.net") || value.match("ficbook.net")
    
    inactive_url_msg = "could not be reached. If the URL is correct and the site is currently down, please try again later."
    inactive_url_timeout = 10 # seconds
    begin
      status = Timeout::timeout(options[:timeout] || inactive_url_timeout) {
        url = Addressable::URI.parse(value)
        response_code = Net::HTTP.start(url.host, url.port) {|http| http.head(url.path.blank? ? '/' : url.path).code}
        active_status = %w[200 301 302 307 308]
        active_status.include? response_code
      }
    rescue
      status = false
    end
    record.errors.add(attribute, options[:message] || inactive_url_msg) unless status
  end
    
end
