# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

$LOAD_PATH.unshift("../../compat") unless $LOAD_PATH.include?("../../compat")
require "webrick"

# copy from gonzui-0.1
# FIXME: it should be deleted if WEBrick supports the method
module WEBrick
  class HTTPRequest
    def parse_accept_language
      if self["Accept-Language"]
        tmp = []
        parts = self["Accept-Language"].split(/,\s*/)
        parts.each {|part|
          if m = /^([\w-]+)(?:;q=([\d]+(?:\.[\d]+)))?$/.match(part)
            lang = m[1]
            q = (m[2] or 1).to_f
            tmp.push([lang, q])
          end
        }
        @accept_language = 
          tmp.sort_by {|lang, q| q}.map {|lang, q| lang}.reverse
      else
        @accept_language = ["en"] # FIXME: should be customizable?
      end
    end

    #undef accept_language
    def accept_language
      if !defined?(@accept_language) || @accept_language.nil?
        parse_accept_language
      end
      return @accept_language
    end

    def gzip_encoding_supported?
      /\bgzip\b/.match(self["accept-encoding"])
    end
  end

  # from httputils.rb
  module HTTPUtils
    undef parse_header
    # FIXME: it should be deleted if WEBRick fix the problem
    def parse_header(raw)
      header = Hash.new([].freeze)
      field = nil
      raw.each{|line|
        case line
#       when /^([A-Za-z0-9_\-]+):\s*(.*?)\s*\z/om
#       when /^([A-Za-z0-9_\-\!\#\$\%\&\'\*\+\.\^\`\|\~]+):\s*(.*?)\s*\z/om
        when /^([A-Za-z0-9_\-~]+):\s*(.*?)\s*\z/om
          field, value = $1, $2
          field.downcase!
          header[field] = [] unless header.has_key?(field)
          header[field] << value
        when /^\s+(.*?)\s*\z/om
          value = $1
          unless field
            raise "bad header '#{line.inspect}'."
          end
          header[field][-1] << " " << value
        else
          raise "bad header '#{line.inspect}'."
        end
      }
      header.each{|key, values|
        values.each{|value|
          value.strip!
          value.gsub!(/\s+/, " ")
        }
      }
      header
    end
    module_function :parse_header

    undef parse_query
    # FIXME: it should be deleted if WEBRick fix the problem
    def parse_query(str)
      query = Hash.new
      if str
        str.split(/[&;]/).each{|x|
          key, val = x.split(/=/,2)
	  next if key.nil?
          key = unescape_form(key)
          val = unescape_form(val.to_s)
          val = FormData.new(val)
          val.name = key
          if query.has_key?(key)
            query[key].append_data(val)
            next
          end
          query[key] = val
        }
      end
      query
    end
    module_function :parse_query
  end
end

if $0 == __FILE__
  require "test/unit"
  $debug = true
end

if $debug
  class TC_HTTPUtils < Test::Unit::TestCase
    def test_parse_accept_language
      # not yet.
    end

    def test_parse_header
      assert_equal('{"header"=>["content"]}',
		   WEBrick::HTTPUtils::parse_header("Header: content").inspect)
      assert_equal('{"~"=>["~"]}',
		   WEBrick::HTTPUtils::parse_header("~: ~\r\n").inspect)
      # real situation
      str = <<EOS
Accept: */*
Accept-Language: ja
~~~~~~~~~~: ~~~~~~~~~~
EOS
      assert_equal('{"~~~~~~~~~~"=>["~~~~~~~~~~"], "accept-language"=>["ja"], "accept"=>["*/*"]}',
		   WEBrick::HTTPUtils::parse_header(str).inspect)
    end

    def test_parse_query
      assert_equal({"a"=>"b"}, WEBrick::HTTPUtils::parse_query("&a=b"))
    end
  end
end
