/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.Cookie = class Cookie
{
    constructor(type, name, value, {header, expires, session, maxAge, path, domain, secure, httpOnly, sameSite} = {})
    {
        console.assert(Object.values(WI.Cookie.Type).includes(type));
        console.assert(typeof name === "string");
        console.assert(typeof value === "string");
        console.assert(!header || typeof header === "string");
        console.assert(!expires || expires instanceof Date);
        console.assert(!session || typeof session === "boolean");
        console.assert(!maxAge || typeof maxAge === "number");
        console.assert(!path || typeof path === "string");
        console.assert(!domain || typeof domain === "string");
        console.assert(!secure || typeof secure === "boolean");
        console.assert(!httpOnly || typeof httpOnly === "boolean");
        console.assert(!sameSite || Object.values(WI.Cookie.SameSiteType).includes(sameSite));

        this._type = type;
        this._name = name;
        this._value = value;
        this._size = this._name.length + this._value.length;

        if (this._type === WI.Cookie.Type.Response) {
            this._header = header || "";
            this._expires = (!session && expires) || null;
            this._session = session || false;
            this._maxAge = maxAge || null;
            this._path = path || null;
            this._domain = domain || null;
            this._secure = secure || false;
            this._httpOnly = httpOnly || false;
            this._sameSite = sameSite || WI.Cookie.SameSiteType.None;
        }
    }

    // Static

    static fromPayload(payload)
    {
        let {name, value, ...options} = payload;
        options.expires = options.expires ? new Date(options.expires.maxDecimals(-3)) : null;

        return new WI.Cookie(WI.Cookie.Type.Response, name, value, options);
    }

    // RFC 6265 defines the HTTP Cookie and Set-Cookie header fields:
    // https://www.ietf.org/rfc/rfc6265.txt

    static parseCookieRequestHeader(header)
    {
        if (!header)
            return [];

        header = header.trim();
        if (!header)
            return [];

        let cookies = [];

        // Cookie: <name> = <value> ( ";" SP <name> = <value> )*?
        // NOTE: Just name/value pairs.

        let pairs = header.split(/; /);
        for (let pair of pairs) {
            let match = pair.match(/^(?<name>[^\s=]+)[ \t]*=[ \t]*(?<value>.*)$/);
            if (!match) {
                WI.reportInternalError("Failed to parse Cookie pair", {header, pair});
                continue;
            }

            let {name, value} = match.groups;
            cookies.push(new WI.Cookie(WI.Cookie.Type.Request, name, value));
        }

        return cookies;
    }

    static displayNameForSameSiteType(sameSiteType)
    {
        switch (sameSiteType) {
        case WI.Cookie.SameSiteType.None:
            return WI.unlocalizedString("None");
        case WI.Cookie.SameSiteType.Lax:
            return WI.unlocalizedString("Lax");
        case WI.Cookie.SameSiteType.Strict:
            return WI.unlocalizedString("Strict");
        default:
            console.error("Invalid SameSite type", sameSiteType);
            return sameSiteType;
        }
    }

    // <https://httpwg.org/http-extensions/rfc6265bis.html#the-samesite-attribute-1>
    static parseSameSiteAttributeValue(attributeValue)
    {
        if (!attributeValue)
            return WI.Cookie.SameSiteType.None;

        switch (attributeValue.toLowerCase()) {
        case "lax":
            return WI.Cookie.SameSiteType.Lax;
        case "strict":
            return WI.Cookie.SameSiteType.Strict;
        }

        return WI.Cookie.SameSiteType.None;
    }

    static parseSetCookieResponseHeader(header)
    {
        if (!header)
            return null;

        // Set-Cookie: <name> = <value> ( ";" SP <attr-maybe-pair> )*?
        // NOTE: Some attributes can have pairs (e.g. "Path=/"), some are only a
        // single word (e.g. "Secure").

        // Parse name/value.
        let nameValueMatch = header.match(/^(?<name>[^\s=]+)[ \t]*=[ \t]*(?<value>[^;]*)/);
        if (!nameValueMatch) {
            WI.reportInternalError("Failed to parse Set-Cookie header", {header});
            return null;
        }

        let {name, value} = nameValueMatch.groups;
        let expires = null;
        let session = false;
        let maxAge = null;
        let path = null;
        let domain = null;
        let secure = false;
        let httpOnly = false;
        let sameSite = WI.Cookie.SameSiteType.None;

        // Parse Attributes
        let remaining = header.substr(nameValueMatch[0].length);
        let attributes = remaining.split(/; ?/);
        for (let attribute of attributes) {
            if (!attribute)
                continue;

            let match = attribute.match(/^(?<name>[^\s=]+)(?:=(?<value>.*))?$/);
            if (!match) {
                console.error("Failed to parse Set-Cookie attribute:", attribute);
                continue;
            }

            let attributeName = match.groups.name;
            let attributeValue = match.groups.value;
            switch (attributeName.toLowerCase()) {
            case "expires":
                console.assert(attributeValue);
                expires = new Date(attributeValue);
                if (isNaN(expires.getTime())) {
                    console.warn("Invalid Expires date:", attributeValue);
                    expires = null;
                }
                break;
            case "max-age":
                console.assert(attributeValue);
                maxAge = parseInt(attributeValue, 10);
                if (isNaN(maxAge) || !/^\d+$/.test(attributeValue)) {
                    console.warn("Invalid MaxAge value:", attributeValue);
                    maxAge = null;
                }
                break;
            case "path":
                console.assert(attributeValue);
                path = attributeValue;
                break;
            case "domain":
                console.assert(attributeValue);
                domain = attributeValue;
                break;
            case "secure":
                console.assert(!attributeValue);
                secure = true;
                break;
            case "httponly":
                console.assert(!attributeValue);
                httpOnly = true;
                break;
            case "samesite":
                sameSite = WI.Cookie.parseSameSiteAttributeValue(attributeValue);
                break;
            default:
                console.warn("Unknown Cookie attribute:", attribute);
                break;
            }
        }

        if (!expires)
            session = true;

        return new WI.Cookie(WI.Cookie.Type.Response, name, value, {header, expires, session, maxAge, path, domain, secure, httpOnly, sameSite});
    }

    // Public

    get type() { return this._type; }
    get name() { return this._name; }
    get value() { return this._value; }
    get header() { return this._header; }
    get expires() { return this._expires; }
    get session() { return this._session; }
    get maxAge() { return this._maxAge; }
    get path() { return this._path; }
    get domain() { return this._domain; }
    get secure() { return this._secure; }
    get httpOnly() { return this._httpOnly; }
    get sameSite() { return this._sameSite; }
    get size() { return this._size; }

    get url()
    {
        let url = this._secure ? "https://" : "http://";
        url += this._domain || "";
        url += this._path || "";
        return url;
    }

    expirationDate(requestSentDate)
    {
        if (this._session)
            return null;

        if (this._maxAge) {
            let startDate = requestSentDate || new Date;
            return new Date(startDate.getTime() + (this._maxAge * 1000));
        }

        return this._expires;
    }

    equals(other)
    {
        return this._type === other.type
            && this._name === other.name
            && this._value === other.value
            && this._header === other.header
            && this._expires?.getTime() === other.expires?.getTime()
            && this._session === other.session
            && this._maxAge === other.maxAge
            && this._path === other.path
            && this._domain === other.domain
            && this._secure === other.secure
            && this._httpOnly === other.httpOnly
            && this._sameSite === other.sameSite;
    }

    toProtocol()
    {
        if (typeof this._name !== "string")
            return null;

        if (typeof this._value !== "string")
            return null;

        if (typeof this._domain !== "string")
            return null;

        if (typeof this._path !== "string")
            return null;

        if (!this._session && !this._expires)
            return null;

        if (!Object.values(WI.Cookie.SameSiteType).includes(this._sameSite))
            return null;

        let json = {
            name: this._name,
            value: this._value,
            domain: this._domain,
            path: this._path,
            expires: this._expires?.getTime(),
            session: this._session,
            httpOnly: !!this._httpOnly,
            secure: !!this._secure,
            sameSite: this._sameSite,
        };

        return json;
    }
};

WI.Cookie.Type = {
    Request: "request",
    Response: "response",
};

// Keep these in sync with the "CookieSameSitePolicy" enum defined by the "Page" domain.
WI.Cookie.SameSiteType = {
    None: "None",
    Lax: "Lax",
    Strict: "Strict",
};
