class WebAgent::CookieManager

def add(given)

def add(given)
  check_domain(given.domain, given.url.host, given.override?)
  domain = given.domain || given.url.host
  path = given.path || given.url.path.sub(%r|/[^/]*\z|, '')
  cookie = nil
  @cookies.synchronize do
    check_expired_cookies
    cookie = @cookies.find { |c|
      c.domain == domain && c.path == path && c.name == given.name
    }
    if !cookie
      cookie = WebAgent::Cookie.new
      cookie.use = true
      @cookies << cookie
    end
  end
  cookie.domain = domain
  cookie.path = path
  cookie.url = given.url
  cookie.name = given.name
  cookie.value = given.value
  cookie.expires = given.expires
  cookie.secure = given.secure?
  cookie.http_only = given.http_only?
  cookie.domain_orig = given.domain
  cookie.path_orig = given.path
  if cookie.discard? || cookie.expires.nil?
    cookie.discard = true
  else
    cookie.discard = false
    @is_saved = false
  end
end

def check_cookie_accept_domain(domain)

Who use it?
def check_cookie_accept_domain(domain)
  unless domain
    return false
  end
  @accept_domains.each{|dom|
    if domain_match(domain, dom)
      return true
    end
  }
  @reject_domains.each{|dom|
    if domain_match(domain, dom)
      return false
    end
  }
  return true
end

def check_domain(domain, hostname, override)

def check_domain(domain, hostname, override)
  return unless domain
  # [DRAFT 12] s. 4.2.2 (does not apply in the case that
  # host name is the same as domain attribute for version 0
  # cookie)
  # I think that this rule has almost the same effect as the
  # tail match of [NETSCAPE].
  if domain !~ /^\./ && hostname != domain
    domain = '.'+domain
  end
  # [NETSCAPE] rule
  if @netscape_rule
    n = domain.scan(/\./).length
    if n < 2
      cookie_error(SpecialError.new, override)
    elsif n == 2
      ## [NETSCAPE] rule
      ok = SPECIAL_DOMAIN.select{|sdomain|
        sdomain == domain[-(sdomain.length)..-1]
      }
      if ok.empty?
        cookie_error(SpecialError.new, override)
      end
    end
  end
  # this implementation does not check RFC2109 4.3.2 case 2;
  # the portion of host not in domain does not contain a dot.
  # according to nsCookieService.cpp in Firefox 3.0.4, Firefox 3.0.4
  # and IE does not check, too.
end

def check_expired_cookies

def check_expired_cookies
  @cookies.reject!{|cookie|
    is_expired = (cookie.expires && (cookie.expires < Time.now.gmtime))
    if is_expired && !cookie.discard?
      @is_saved = false
    end
    is_expired
  }
end

def cookie_error(err, override)

not tested well; used only netscape_rule = true.
def cookie_error(err, override)
  if !err.kind_of?(ErrorOverrideOK) || !override
    raise err
  end
end

def cookies=(cookies)

def cookies=(cookies)
  if cookies.is_a?(SynchronizedArray)
    @cookies = cookies
  else
    @cookies = SynchronizedArray.new(cookies)
  end
end

def find(url)

def find(url)
  return nil if @cookies.empty?
  cookie_list = Array.new
  @cookies.each{|cookie|
    is_expired = (cookie.expires && (cookie.expires < Time.now.gmtime))
    if cookie.use? && !is_expired && cookie.match?(url)
      if cookie_list.select{|c1| c1.name == cookie.name}.empty?
        cookie_list << cookie
      end
    end
  }
  return make_cookie_str(cookie_list)
end

def initialize(file=nil)

def initialize(file=nil)
  @cookies = SynchronizedArray.new
  @cookies_file = file
  @is_saved = true
  @reject_domains = Array.new
  @accept_domains = Array.new
  @netscape_rule = false
end

def load_cookies

def load_cookies
  return if !File.readable?(@cookies_file)
  @cookies.synchronize do
    @cookies.clear
    File.open(@cookies_file,'r'){|f|
      while line = f.gets
        cookie = WebAgent::Cookie.new
        @cookies << cookie
        col = line.chomp.split(/\t/)
        cookie.url = HTTPClient::Util.urify(col[0])
        cookie.name = col[1]
        cookie.value = col[2]
        if col[3].empty? or col[3] == '0'
          cookie.expires = nil
        else
          cookie.expires = Time.at(col[3].to_i).gmtime
        end
        cookie.domain = col[4]
        cookie.path = col[5]
        cookie.set_flag(col[6])
      end
    }
  end
end

def make_cookie_str(cookie_list)

def make_cookie_str(cookie_list)
  if cookie_list.empty?
    return nil
  end
  ret = ''
  c = cookie_list.shift
  ret += "#{c.name}=#{c.value}"
  cookie_list.each{|cookie|
    ret += "; #{cookie.name}=#{cookie.value}"
  }
  return ret
end

def parse(str, url)

def parse(str, url)
  cookie = WebAgent::Cookie.new
  cookie.parse(str, url)
  add(cookie)
end

def save_all_cookies(force = nil, save_unused = true, save_discarded = true)

def save_all_cookies(force = nil, save_unused = true, save_discarded = true)
  @cookies.synchronize do
    check_expired_cookies
    if @is_saved and !force
      return
    end
    File.open(@cookies_file, 'w') do |f|
      @cookies.each do |cookie|
        if (cookie.use? or save_unused) and
          (!cookie.discard? or save_discarded)
          f.print(cookie.url.to_s,"\t",
                  cookie.name,"\t",
                  cookie.value,"\t",
                  cookie.expires.to_i,"\t",
                  cookie.domain,"\t",
                  cookie.path,"\t",
                  cookie.flag,"\n")
        end
      end
    end
  end
  @is_saved = true
end

def save_cookies(force = nil)

def save_cookies(force = nil)
  save_all_cookies(force, false, false)
end