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

$LOAD_PATH.unshift("../../compat") unless $LOAD_PATH.include?("../../compat")
require "webrick/cookie"
$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/config"
require "qwik/format-xml"

module Qwik
  class Response
    COOKIE_EXP = 60*60*24*30 # 30 days

    MIME_TYPES = {
      "smil"=>"application/smil",
      "swf"=>"application/x-shockwave-flash",
      "ico"=>"image/bitmap", # ?
      "png"=>"image/png",
      "3gp"=>"video/3gpp",
      "tgz"=>"application/octet-stream",
      "gz"=>"application/octet-stream",
    }

    def initialize(config)
      @config = config
      clear
    end
    attr_accessor :mimetypes
    attr_accessor :body, :status
    attr_reader :headers # for test
    attr_reader :cookies # for test
    attr_accessor :basicauth
    attr_accessor :sessionid

    def clear
      @body = nil
      @status = 200
      @cookies = []
      @headers = {}
      @mimetypes = {}
      @basicauth = nil
      @sessionid = nil
    end

    def set_webrick(response)
      make_mimetypes(response.config[:MimeTypes])
    end

    def make_mimetypes(mimetypes)
      @mimetypes = mimetypes
      @mimetypes.update(MIME_TYPES)
    end

    def [](k)
      @headers[k]
    end

    def []=(k, v)
      @headers[k] = v
    end

    def set_cookies(user, pass)
      set_cookie("user", user)
      set_cookie("pass", pass)
    end

    def set_cookie(k, v)
      @cookies << make_cookie(k, v)
    end

    def clear_cookies
      # Set cookies to 1 hour ago, to clear cookies from browser.
      clear_cookie("user")
      clear_cookie("pass")
      clear_cookie("sid")
    end

    def clear_cookie(k)
      @cookies << make_cookie(k, "", -60*60)
    end

    def make_cookie(k, v, exp=COOKIE_EXP)
      c = WEBrick::Cookie.new(k, v)
      c.path = "/"
      c.expires = Time.now + exp
      c
    end
    private :make_cookie

    def setback_body(body)
      case body
      when Array # wabisabi
	return body.format_xml
      when File
	return body # do not convert
      when String
	return body
      else
	return body.to_s
      end
    end

    def setback(response)
      response.body = setback_body(@body)
      response.status = @status
      @cookies.each {|c| response.cookies << c }
      @headers.each {|k, v| response[k] = v }
    end
  end
end

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

if $debug
  class TC_Response < Test::Unit::TestCase
    def setup
      config = Qwik::Config.new
      @res = Qwik::Response.new(config)
    end

    def test_all
      # test_mimetypes
      mt = {}
      @res.make_mimetypes(mt)
      assert_equal("application/x-shockwave-flash", mt["swf"])
      assert_equal("application/smil", mt["smil"])
      assert_equal("image/bitmap", mt["ico"])
      assert_equal("image/png", mt["png"])
      assert_equal("video/3gpp", mt["3gp"])

      # test_headers
      @res["X-Test-Header"] = "t1"
      assert_equal("t1", @res["X-Test-Header"])
      @res.clear
      assert_equal(nil, @res["X-Test-Header"])

      # test_cookie
      @res.set_cookies("t@e.com", "testpass")
      assert_equal(2, @res.cookies.length)
      @res.clear_cookies
      #assert_equal(4, @res.cookies.length)
      @res.clear
      assert_equal(0, @res.cookies.length)

      # test_setback
      assert_equal("", @res.setback_body([]))
      assert_equal("<t\n></t\n>", @res.setback_body([:t, ""]))
      assert_equal("t", @res.setback_body("t"))
      assert_equal("", @res.setback_body(nil))
    end
  end
end
