module CookieRequest

using Dates, URIs
using ..Cookies, ..Messages, ..Strings

# default global cookie jar
const COOKIEJAR = CookieJar()

export cookielayer, COOKIEJAR

"""
    cookielayer(handler) -> handler

Check for host-appropriate cookies to include in the outgoing request
from the `cookiejar` keyword argument (by default, a global cookiejar is used).
Store "Set-Cookie" cookies from the response headers.
"""
function cookielayer(handler)
    return function managecookies(req::Request; cookies=true, cookiejar::CookieJar=COOKIEJAR, kw...)
        if cookies === true || (cookies isa AbstractDict && !isempty(cookies))
            url = req.url
            cookiestosend = Cookies.getcookies!(cookiejar, url)
            if !(cookies isa Bool)
                for (name, value) in cookies
                    push!(cookiestosend, Cookie(name, value))
                end
            end
            if !isempty(cookiestosend)
                existingcookie = header(req.headers, "Cookie")
                if existingcookie != "" && haskey(req.context, :includedCookies)
                    # this is a redirect where we previously included cookies
                    # we want to filter those out to avoid duplicate cookie sending
                    # and the case where a cookie was set to expire from the 1st request
                    previouscookies = Cookies.cookies(req)
                    previouslyincluded = req.context[:includedCookies]
                    filtered = filter(x -> !(x.name in previouslyincluded), previouscookies)
                    existingcookie = stringify("", filtered)
                end
                setheader(req.headers, "Cookie" => stringify(existingcookie, cookiestosend))
                req.context[:includedCookies] = map(x -> x.name, cookiestosend)
            end
            res = handler(req; kw...)
            Cookies.setcookies!(cookiejar, url, res.headers)
            return res
        else
            # skip
            return handler(req; kw...)
        end
    end
end

end # module CookieRequest
