/*
 * Copyright (C) 2019 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.LocalResourceOverride = class LocalResourceOverride extends WI.Object
{
    constructor(url, type, localResource, {resourceErrorType, isCaseSensitive, isRegex, disabled} = {})
    {
        console.assert(url && typeof url === "string", url);
        console.assert(Object.values(WI.LocalResourceOverride.InterceptType).includes(type), type);
        console.assert(localResource instanceof WI.LocalResource, localResource);
        console.assert(!localResource.localResourceOverride, localResource);
        console.assert(!resourceErrorType || Object.values(WI.LocalResourceOverride.ResourceErrorType).includes(resourceErrorType), resourceErrorType);
        console.assert(isCaseSensitive === undefined || typeof isCaseSensitive === "boolean", isCaseSensitive);
        console.assert(isRegex === undefined || typeof isRegex === "boolean", isRegex);
        console.assert(disabled === undefined || typeof disabled === "boolean", disabled);

        super();

        this._url = WI.urlWithoutFragment(url);
        this._urlComponents = null;
        this._type = type;
        this._localResource = localResource;
        this._resourceErrorType = resourceErrorType || WI.LocalResourceOverride.ResourceErrorType.General;
        this._isCaseSensitive = isCaseSensitive !== undefined ? isCaseSensitive : true;
        this._isRegex = isRegex !== undefined ? isRegex : false;
        this._disabled = disabled !== undefined ? disabled : false;

        this._localResource._localResourceOverride = this;
    }

    // Static

    static create(url, type, {requestURL, requestMethod, requestHeaders, requestData, responseMIMEType, responseContent, responseBase64Encoded, responseStatusCode, responseStatusText, responseHeaders, resourceErrorType, isCaseSensitive, isRegex, disabled} = {})
    {
        let localResource = new WI.LocalResource({
            request: {
                url: requestURL || url || "",
                method: requestMethod,
                headers: requestHeaders,
                data: requestData,
            },
            response: {
                headers: responseHeaders,
                mimeType: responseMIMEType,
                statusCode: responseStatusCode,
                statusText: responseStatusText,
                content: responseContent,
                base64Encoded: responseBase64Encoded,
            },
        });
        return new WI.LocalResourceOverride(url, type, localResource, {resourceErrorType, isCaseSensitive, isRegex, disabled});
    }

    static displayNameForNetworkStageOfType(type)
    {
        switch (type) {
        case WI.LocalResourceOverride.InterceptType.Block:
        case WI.LocalResourceOverride.InterceptType.Request:
            return WI.UIString("Request Override", "Request Override @ Local Override Network Stage", "Text indicating that the local override replaces the request of the network activity.");

        case WI.LocalResourceOverride.InterceptType.Response:
        case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork:
            return WI.UIString("Response Override", "Response Override @ Local Override Network Stage", "Text indicating that the local override replaces the response of the network activity.");
        }

        console.assert(false, "Unknown type: ", type);
        return "";
    }

    static displayNameForType(type)
    {
        switch (type) {
        case WI.LocalResourceOverride.InterceptType.Block:
            return WI.UIString("Block", "Block @ Local Override Type", "Text indicating that the local override will always block the network activity.");

        case WI.LocalResourceOverride.InterceptType.Request:
            return WI.UIString("Request", "Request @ Local Override Type", "Text indicating that the local override intercepts the request phase of network activity.");

        case WI.LocalResourceOverride.InterceptType.Response:
            return WI.UIString("Response", "Response @ Local Override Type", "Text indicating that the local override intercepts the response phase of network activity.");

        case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork:
            return WI.UIString("Response (skip network)", "Response (skip network) @ Local Override Type", "Text indicating that the local override will skip all network activity and instead immediately serve the response.");
        }

        console.assert(false, "Unknown type: ", type);
        return "";
    }

    static displayNameForResourceErrorType(resourceErrorType)
    {
        switch (resourceErrorType) {
        case WI.LocalResourceOverride.ResourceErrorType.AccessControl:
            return WI.UIString("Access Control", "Access Control @ Local Override Type", "Text indicating that the local override will block the network activity with an access error.");

        case WI.LocalResourceOverride.ResourceErrorType.Cancellation:
            return WI.UIString("Cancellation", "Cancellation @ Local Override Type", "Text indicating that the local override will block the network activity with a cancellation error.");

        case WI.LocalResourceOverride.ResourceErrorType.General:
            return WI.UIString("General", "General @ Local Override Type", "Text indicating that the local override will block the network activity with a general error.");

        case WI.LocalResourceOverride.ResourceErrorType.Timeout:
            return WI.UIString("Timeout", "Timeout @ Local Override Type", "Text indicating that the local override will block the network activity with an timeout error.");
        }

        console.assert(false, "Unknown resource error type: ", resourceErrorType);
        return "";
    }

    // Import / Export

    static fromJSON(json)
    {
        let {url, type, localResource: localResourceJSON, resourceErrorType, isCaseSensitive, isRegex, disabled} = json;

        let localResource = WI.LocalResource.fromJSON(localResourceJSON);

        // COMPATIBILITY (iOS 13.4): Network.interceptWithRequest/Network.interceptRequestWithResponse did not exist yet.
        url ??= localResource.url;
        type ??= WI.LocalResourceOverride.InterceptType.Response;

        return new WI.LocalResourceOverride(url, type, localResource, {resourceErrorType, isCaseSensitive, isRegex, disabled});
    }

    toJSON(key)
    {
        let json = {
            url: this._url,
            type: this._type,
            localResource: this._localResource.toJSON(key),
            isCaseSensitive: this._isCaseSensitive,
            isRegex: this._isRegex,
            disabled: this._disabled,
        };

        if (this._resourceErrorType)
            json.resourceErrorType = this._resourceErrorType;

        if (key === WI.ObjectStore.toJSONSymbol)
            json[WI.objectStores.localResourceOverrides.keyPath] = this._url;

        return json;
    }

    // Public

    get url() { return this._url; }
    get type() { return this._type; }
    get localResource() { return this._localResource; }
    get isCaseSensitive() { return this._isCaseSensitive; }
    get isRegex() { return this._isRegex; }

    get urlComponents()
    {
        if (!this._urlComponents)
            this._urlComponents = parseURL(this._url);
        return this._urlComponents;
    }

    get resourceErrorType()
    {
        return this._resourceErrorType;
    }

    set resourceErrorType(resourceErrorType)
    {
        console.assert(Object.values(WI.LocalResourceOverride.ResourceErrorType).includes(resourceErrorType), resourceErrorType);

        if (this._resourceErrorType === resourceErrorType)
            return;

        this._resourceErrorType = resourceErrorType;

        this.dispatchEventToListeners(WI.LocalResourceOverride.Event.ResourceErrorTypeChanged);
    }

    get disabled()
    {
        return this._disabled;
    }

    set disabled(disabled)
    {
        if (this._disabled === disabled)
            return;

        this._disabled = !!disabled;

        this.dispatchEventToListeners(WI.LocalResourceOverride.Event.DisabledChanged);
    }

    get displayName()
    {
        return this.displayURL();
    }

    displayURL({full} = {})
    {
        if (this._isRegex)
            return "/" + this._url + "/" + (!this._isCaseSensitive ? "i" : "");

        let displayName = full ? this._url : WI.displayNameForURL(this._url, this.urlComponents);
        if (!this._isCaseSensitive)
            displayName = WI.UIString("%s (Case Insensitive)", "%s (Case Insensitive) @ Local Override", "Label for case-insensitive URL match pattern of a local override.").format(displayName);
        return displayName;
    }

    generateRequestRedirectURL(url)
    {
        console.assert(this._type === WI.LocalResourceOverride.InterceptType.Request, this);

        let redirectURL = this._localResource.url;
        if (!redirectURL)
            return null;

        if (this._isRegex)
            return url.replace(this._urlRegex, redirectURL);

        return redirectURL;
    }

    get canMapToFile()
    {
        if (!WI.LocalResource.canMapToFile())
            return false;

        switch (this._type) {
        case WI.LocalResourceOverride.InterceptType.Block:
        case WI.LocalResourceOverride.InterceptType.Request:
            return false;

        case WI.LocalResourceOverride.InterceptType.Response:
        case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork:
            return true;
        }

        console.assert(false, "not reached");
        return false;
    }

    matches(url)
    {
        url = WI.urlWithoutFragment(url);

        if (this._isRegex)
            return this._urlRegex.test(url);

        if (!this._isCaseSensitive)
            return url.toLowerCase() === this._url.toLowerCase();

        return url === this._url;
    }

    equals(localResourceOverrideOrSerializedData)
    {
        console.assert(localResourceOverrideOrSerializedData instanceof WI.LocalResourceOverride || (localResourceOverrideOrSerializedData && typeof localResourceOverrideOrSerializedData === "object"), localResourceOverrideOrSerializedData);

        return localResourceOverrideOrSerializedData.url === this._url
            && localResourceOverrideOrSerializedData.isCaseSensitive === this._isCaseSensitive
            && localResourceOverrideOrSerializedData.isRegex === this._isRegex;
    }

    // Protected

    saveIdentityToCookie(cookie)
    {
        cookie["local-resource-override-url"] = this._url;
        cookie["local-resource-override-type"] = this._type;
        cookie["local-resource-override-is-case-sensitive"] = this._isCaseSensitive;
        cookie["local-resource-override-is-regex"] = this._isRegex;
        cookie["local-resource-override-disabled"] = this._disabled;
    }

    // Private

    get _urlRegex()
    {
        console.assert(this._isRegex);
        return new RegExp(this._url, !this._isCaseSensitive ? "i" : "");
    }
};

WI.LocalResourceOverride.TypeIdentifier = "local-resource-override";

WI.LocalResourceOverride.InterceptType = {
    Block: "block",
    Request: "request",
    Response: "response",
    ResponseSkippingNetwork: "response-skipping-network",
};

WI.LocalResourceOverride.ResourceErrorType = {
    AccessControl: "AccessControl",
    Cancellation: "Cancellation",
    General: "General",
    Timeout: "Timeout",
};

WI.LocalResourceOverride.Event = {
    DisabledChanged: "local-resource-override-disabled-state-did-change",
    ResourceErrorTypeChanged: "local-resource-override-resource-error-type-changed",
};
