/*
 * 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, maxAge, path, domain, secure, httpOnly, sameSite, size} = {})
    {
        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(!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));
        console.assert(!size || typeof size === "number");

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

        if (this._type === WI.Cookie.Type.Response) {
            this._header = header || "";
            this._expires = expires || null;
            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) : 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 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;
            }
        }

        return new WI.Cookie(WI.Cookie.Type.Response, name, value, {header, expires, 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 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._maxAge) {
            let startDate = requestSentDate || new Date;
            return new Date(startDate.getTime() + (this._maxAge * 1000));
        }

        return this._expires;
    }
};

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",
};
