/*
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 * Copyright (C) 2011 Google 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.Resource = class Resource extends WI.SourceCode
{
    constructor(url, {mimeType, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, requestSentTimestamp, requestSentWalltime, initiatorCallFrames, initiatorSourceCodeLocation, initiatorNode, originalRequestWillBeSentTimestamp} = {})
    {
        super();

        console.assert(url);

        if (type in WI.Resource.Type)
            type = WI.Resource.Type[type];

        this._url = url;
        this._urlComponents = null;
        this._mimeType = mimeType;
        this._mimeTypeComponents = null;
        this._type = Resource.resolvedType(type, mimeType);
        this._loaderIdentifier = loaderIdentifier || null;
        this._requestIdentifier = requestIdentifier || null;
        this._queryStringParameters = undefined;
        this._requestFormParameters = undefined;
        this._requestMethod = requestMethod || null;
        this._requestData = requestData || null;
        this._requestHeaders = requestHeaders || {};
        this._responseHeaders = {};
        this._requestCookies = null;
        this._responseCookies = null;
        this._serverTimingEntries = null;
        this._parentFrame = null;
        this._initiatorCallFrames = initiatorCallFrames || null;
        this._initiatorSourceCodeLocation = initiatorSourceCodeLocation || null;
        this._initiatorNode = initiatorNode || null;
        this._initiatedResources = [];
        this._originalRequestWillBeSentTimestamp = originalRequestWillBeSentTimestamp || null;
        this._requestSentTimestamp = requestSentTimestamp || NaN;
        this._requestSentWalltime = requestSentWalltime || NaN;
        this._responseReceivedTimestamp = NaN;
        this._lastDataReceivedTimestamp = NaN;
        this._finishedOrFailedTimestamp = NaN;
        this._finishThenRequestContentPromise = null;
        this._statusCode = NaN;
        this._statusText = null;
        this._cached = false;
        this._canceled = false;
        this._finished = false;
        this._failed = false;
        this._failureReasonText = null;
        this._receivedNetworkLoadMetrics = false;
        this._responseSource = WI.Resource.ResponseSource.Unknown;
        this._security = null;
        this._timingData = new WI.ResourceTimingData(this);
        this._protocol = null;
        this._priority = WI.Resource.NetworkPriority.Unknown;
        this._remoteAddress = null;
        this._connectionIdentifier = null;
        this._target = targetId ? WI.targetManager.targetForIdentifier(targetId) : WI.mainTarget;
        this._redirects = [];

        // Exact sizes if loaded over the network or cache.
        this._requestHeadersTransferSize = NaN;
        this._requestBodyTransferSize = NaN;
        this._responseHeadersTransferSize = NaN;
        this._responseBodyTransferSize = NaN;
        this._responseBodySize = NaN;
        this._cachedResponseBodySize = NaN;

        // Estimated sizes (if backend does not provide metrics).
        this._estimatedSize = NaN;
        this._estimatedTransferSize = NaN;
        this._estimatedResponseHeadersSize = NaN;

        if (this._initiatorSourceCodeLocation && this._initiatorSourceCodeLocation.sourceCode instanceof WI.Resource)
            this._initiatorSourceCodeLocation.sourceCode.addInitiatedResource(this);
    }

    // Static

    static resolvedType(type, mimeType)
    {
        if (type && type !== WI.Resource.Type.Other)
            return type;

        return Resource.typeFromMIMEType(mimeType);
    }

    static typeFromMIMEType(mimeType)
    {
        if (!mimeType)
            return WI.Resource.Type.Other;

        mimeType = parseMIMEType(mimeType).type;

        if (mimeType in WI.Resource._mimeTypeMap)
            return WI.Resource._mimeTypeMap[mimeType];

        if (mimeType.startsWith("image/"))
            return WI.Resource.Type.Image;

        if (mimeType.startsWith("font/"))
            return WI.Resource.Type.Font;

        return WI.Resource.Type.Other;
    }

    static displayNameForType(type, plural)
    {
        switch (type) {
        case WI.Resource.Type.Document:
            if (plural)
                return WI.UIString("Documents");
            return WI.UIString("Document");
        case WI.Resource.Type.StyleSheet:
            if (plural)
                return WI.UIString("Style Sheets");
            return WI.UIString("Style Sheet");
        case WI.Resource.Type.Image:
            if (plural)
                return WI.UIString("Images");
            return WI.UIString("Image");
        case WI.Resource.Type.Font:
            if (plural)
                return WI.UIString("Fonts");
            return WI.UIString("Font");
        case WI.Resource.Type.Script:
            if (plural)
                return WI.UIString("Scripts");
            return WI.UIString("Script");
        case WI.Resource.Type.XHR:
            if (plural)
                return WI.UIString("XHRs");
            return WI.UIString("XHR");
        case WI.Resource.Type.Fetch:
            if (plural)
                return WI.UIString("Fetches", "Resources loaded via 'fetch' method");
            return WI.repeatedUIString.fetch();
        case WI.Resource.Type.Ping:
            if (plural)
                return WI.UIString("Pings");
            return WI.UIString("Ping");
        case WI.Resource.Type.Beacon:
            if (plural)
                return WI.UIString("Beacons");
            return WI.UIString("Beacon");
        case WI.Resource.Type.WebSocket:
            if (plural)
                return WI.UIString("Sockets");
            return WI.UIString("Socket");
        case WI.Resource.Type.Other:
            return WI.UIString("Other");
        default:
            console.error("Unknown resource type", type);
            return null;
        }
    }

    static classNamesForResource(resource)
    {
        let classes = [];

        let isOverride = resource.isLocalResourceOverride;
        let wasOverridden = resource.responseSource === WI.Resource.ResponseSource.InspectorOverride;
        let shouldBeOverridden = resource.isLoading() && WI.networkManager.localResourceOverrideForURL(resource.url);
        if (isOverride || wasOverridden || shouldBeOverridden)
            classes.push("override");

        if (resource.type === WI.Resource.Type.Other) {
            if (resource.requestedByteRange)
                classes.push("resource-type-range");
        } else
            classes.push(resource.type);

        return classes;
    }

    static displayNameForProtocol(protocol)
    {
        switch (protocol) {
        case "h2":
            return "HTTP/2";
        case "http/1.0":
            return "HTTP/1.0";
        case "http/1.1":
            return "HTTP/1.1";
        case "spdy/2":
            return "SPDY/2";
        case "spdy/3":
            return "SPDY/3";
        case "spdy/3.1":
            return "SPDY/3.1";
        default:
            return null;
        }
    }

    static comparePriority(a, b)
    {
        console.assert(typeof a === "symbol");
        console.assert(typeof b === "symbol");

        const map = {
            [WI.Resource.NetworkPriority.Unknown]: 0,
            [WI.Resource.NetworkPriority.Low]: 1,
            [WI.Resource.NetworkPriority.Medium]: 2,
            [WI.Resource.NetworkPriority.High]: 3,
        };

        let aNum = map[a] || 0;
        let bNum = map[b] || 0;
        return aNum - bNum;
    }

    static displayNameForPriority(priority)
    {
        switch (priority) {
        case WI.Resource.NetworkPriority.Low:
            return WI.UIString("Low");
        case WI.Resource.NetworkPriority.Medium:
            return WI.UIString("Medium");
        case WI.Resource.NetworkPriority.High:
            return WI.UIString("High");
        default:
            return null;
        }
    }

    static responseSourceFromPayload(source)
    {
        if (!source)
            return WI.Resource.ResponseSource.Unknown;

        switch (source) {
        case NetworkAgent.ResponseSource.Unknown:
            return WI.Resource.ResponseSource.Unknown;
        case NetworkAgent.ResponseSource.Network:
            return WI.Resource.ResponseSource.Network;
        case NetworkAgent.ResponseSource.MemoryCache:
            return WI.Resource.ResponseSource.MemoryCache;
        case NetworkAgent.ResponseSource.DiskCache:
            return WI.Resource.ResponseSource.DiskCache;
        case NetworkAgent.ResponseSource.ServiceWorker:
            return WI.Resource.ResponseSource.ServiceWorker;
        case NetworkAgent.ResponseSource.InspectorOverride:
            return WI.Resource.ResponseSource.InspectorOverride;
        default:
            console.error("Unknown response source type", source);
            return WI.Resource.ResponseSource.Unknown;
        }
    }

    static networkPriorityFromPayload(priority)
    {
        switch (priority) {
        case NetworkAgent.MetricsPriority.Low:
            return WI.Resource.NetworkPriority.Low;
        case NetworkAgent.MetricsPriority.Medium:
            return WI.Resource.NetworkPriority.Medium;
        case NetworkAgent.MetricsPriority.High:
            return WI.Resource.NetworkPriority.High;
        default:
            console.error("Unknown metrics priority", priority);
            return WI.Resource.NetworkPriority.Unknown;
        }
    }

    static connectionIdentifierFromPayload(connectionIdentifier)
    {
        // Map backend connection identifiers to an easier to read number.
        if (!WI.Resource.connectionIdentifierMap) {
            WI.Resource.connectionIdentifierMap = new Map;
            WI.Resource.nextConnectionIdentifier = 1;
        }

        let id = WI.Resource.connectionIdentifierMap.get(connectionIdentifier);
        if (id)
            return id;

        id = WI.Resource.nextConnectionIdentifier++;
        WI.Resource.connectionIdentifierMap.set(connectionIdentifier, id);
        return id;
    }

    // Public

    get url() { return this._url; }
    get mimeType() { return this._mimeType; }
    get target() { return this._target; }
    get type() { return this._type; }
    get loaderIdentifier() { return this._loaderIdentifier; }
    get requestIdentifier() { return this._requestIdentifier; }
    get requestMethod() { return this._requestMethod; }
    get requestData() { return this._requestData; }
    get initiatorCallFrames() { return this._initiatorCallFrames; }
    get initiatorSourceCodeLocation() { return this._initiatorSourceCodeLocation; }
    get initiatorNode() { return this._initiatorNode; }
    get initiatedResources() { return this._initiatedResources; }
    get originalRequestWillBeSentTimestamp() { return this._originalRequestWillBeSentTimestamp; }
    get statusCode() { return this._statusCode; }
    get statusText() { return this._statusText; }
    get responseSource() { return this._responseSource; }
    get security() { return this._security; }
    get timingData() { return this._timingData; }
    get protocol() { return this._protocol; }
    get priority() { return this._priority; }
    get remoteAddress() { return this._remoteAddress; }
    get connectionIdentifier() { return this._connectionIdentifier; }
    get parentFrame() { return this._parentFrame; }
    get finished() { return this._finished; }
    get failed() { return this._failed; }
    get canceled() { return this._canceled; }
    get failureReasonText() { return this._failureReasonText; }
    get requestHeaders() { return this._requestHeaders; }
    get responseHeaders() { return this._responseHeaders; }
    get requestSentTimestamp() { return this._requestSentTimestamp; }
    get requestSentWalltime() { return this._requestSentWalltime; }
    get responseReceivedTimestamp() { return this._responseReceivedTimestamp; }
    get lastDataReceivedTimestamp() { return this._lastDataReceivedTimestamp; }
    get finishedOrFailedTimestamp() { return this._finishedOrFailedTimestamp; }
    get cached() { return this._cached; }
    get requestHeadersTransferSize() { return this._requestHeadersTransferSize; }
    get requestBodyTransferSize() { return this._requestBodyTransferSize; }
    get responseHeadersTransferSize() { return this._responseHeadersTransferSize; }
    get responseBodyTransferSize() { return this._responseBodyTransferSize; }
    get cachedResponseBodySize() { return this._cachedResponseBodySize; }
    get redirects() { return this._redirects; }

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

    get loadedSecurely()
    {
        if (this.urlComponents.scheme !== "https" && this.urlComponents.scheme !== "wss" && this.urlComponents.scheme !== "sftp")
            return false;
        if (isNaN(this._timingData.secureConnectionStart) && !isNaN(this._timingData.connectionStart))
            return false;
        return true;
    }

    get isScript()
    {
        return this._type === Resource.Type.Script;
    }

    get supportsScriptBlackboxing()
    {
        if (this.isLocalResourceOverride)
            return false;
        if (!this.finished || this.failed)
            return false;
        return super.supportsScriptBlackboxing;
    }

    get displayName()
    {
        return WI.displayNameForURL(this._url, this.urlComponents);
    }

    get displayURL()
    {
        const isMultiLine = true;
        const dataURIMaxSize = 64;
        return WI.truncateURL(this._url, isMultiLine, dataURIMaxSize);
    }

    get mimeTypeComponents()
    {
        if (!this._mimeTypeComponents)
            this._mimeTypeComponents = parseMIMEType(this._mimeType);
        return this._mimeTypeComponents;
    }

    get syntheticMIMEType()
    {
        // Resources are often transferred with a MIME-type that doesn't match the purpose the
        // resource was loaded for, which is what WI.Resource.Type represents.
        // This getter generates a MIME-type, if needed, that matches the resource type.

        // If the type matches the Resource.Type of the MIME-type, then return the actual MIME-type.
        if (this._type === WI.Resource.typeFromMIMEType(this._mimeType))
            return this._mimeType;

        // Return the default MIME-types for the Resource.Type, since the current MIME-type
        // does not match what is expected for the Resource.Type.
        switch (this._type) {
        case WI.Resource.Type.StyleSheet:
            return "text/css";
        case WI.Resource.Type.Script:
            return "text/javascript";
        }

        // Return the actual MIME-type since we don't have a better synthesized one to return.
        return this._mimeType;
    }

    createObjectURL()
    {
        let revision = this.currentRevision;
        let blobContent = revision.blobContent;
        if (blobContent)
            return URL.createObjectURL(blobContent)

        // If content is not available, fallback to using original URL.
        // The client may try to revoke it, but nothing will happen.
        return this._url;
    }

    isMainResource()
    {
        return this._parentFrame ? this._parentFrame.mainResource === this : false;
    }

    get isLocalResourceOverride()
    {
        return false;
    }

    addInitiatedResource(resource)
    {
        if (!(resource instanceof WI.Resource))
            return;

        this._initiatedResources.push(resource);

        this.dispatchEventToListeners(WI.Resource.Event.InitiatedResourcesDidChange);
    }

    get queryStringParameters()
    {
        if (this._queryStringParameters === undefined)
            this._queryStringParameters = parseQueryString(this.urlComponents.queryString, true);
        return this._queryStringParameters;
    }

    get requestFormParameters()
    {
        if (this._requestFormParameters === undefined)
            this._requestFormParameters = this.hasRequestFormParameters() ? parseQueryString(this.requestData, true) : null;
        return this._requestFormParameters;
    }

    get requestDataContentType()
    {
        return this._requestHeaders.valueForCaseInsensitiveKey("Content-Type") || null;
    }

    get requestCookies()
    {
        if (!this._requestCookies)
            this._requestCookies = WI.Cookie.parseCookieRequestHeader(this._requestHeaders.valueForCaseInsensitiveKey("Cookie"));

        return this._requestCookies;
    }

    get responseCookies()
    {
        if (!this._responseCookies) {
            // FIXME: The backend sends multiple "Set-Cookie" headers in one "Set-Cookie" with multiple values
            // separated by ", ". This doesn't allow us to safely distinguish between a ", " that separates
            // multiple headers or one that may be valid part of a Cookie's value or attribute, such as the
            // ", " in the the date format "Expires=Tue, 03-Oct-2017 04:39:21 GMT". To improve heuristics
            // we do a negative lookahead for numbers, but we can still fail on cookie values containing ", ".
            let rawCombinedHeader = this._responseHeaders.valueForCaseInsensitiveKey("Set-Cookie") || "";
            let setCookieHeaders = rawCombinedHeader.split(/, (?![0-9])/);
            let cookies = [];
            for (let header of setCookieHeaders) {
                let cookie = WI.Cookie.parseSetCookieResponseHeader(header);
                if (cookie)
                    cookies.push(cookie);
            }
            this._responseCookies = cookies;
        }

        return this._responseCookies;
    }

    get requestSentDate()
    {
        return isNaN(this._requestSentWalltime) ? null : new Date(this._requestSentWalltime * 1000);
    }

    get lastRedirectReceivedTimestamp()
    {
        return this._redirects.length ? this._redirects.lastValue.timestamp : NaN;
    }

    get firstTimestamp()
    {
        return this.timingData.startTime || this.lastRedirectReceivedTimestamp || this.responseReceivedTimestamp || this.lastDataReceivedTimestamp || this.finishedOrFailedTimestamp;
    }

    get lastTimestamp()
    {
        return this.timingData.responseEnd || this.lastDataReceivedTimestamp || this.responseReceivedTimestamp || this.lastRedirectReceivedTimestamp || this.requestSentTimestamp;
    }

    get latency()
    {
        return this.timingData.responseStart - this.timingData.requestStart;
    }

    get receiveDuration()
    {
        return this.timingData.responseEnd - this.timingData.responseStart;
    }

    get totalDuration()
    {
        return this.timingData.responseEnd - this.timingData.startTime;
    }

    get size()
    {
        if (!isNaN(this._cachedResponseBodySize))
            return this._cachedResponseBodySize;

        if (!isNaN(this._responseBodySize) && this._responseBodySize !== 0)
            return this._responseBodySize;

        return this._estimatedSize;
    }

    get networkEncodedSize()
    {
        return this._responseBodyTransferSize;
    }

    get networkDecodedSize()
    {
        return this._responseBodySize;
    }

    get networkTotalTransferSize()
    {
        return this._responseHeadersTransferSize + this._responseBodyTransferSize;
    }

    get estimatedNetworkEncodedSize()
    {
        let exact = this.networkEncodedSize;
        if (!isNaN(exact))
            return exact;

        if (this._cached)
            return 0;

        // FIXME: <https://webkit.org/b/158463> Network: Correctly report encoded data length (transfer size) from CFNetwork to NetworkResourceLoader
        // macOS provides the decoded transfer size instead of the encoded size
        // for estimatedTransferSize. So prefer the "Content-Length" property
        // on mac if it is available.
        if (WI.Platform.name === "mac") {
            let contentLength = Number(this._responseHeaders.valueForCaseInsensitiveKey("Content-Length"));
            if (!isNaN(contentLength))
                return contentLength;
        }

        if (!isNaN(this._estimatedTransferSize))
            return this._estimatedTransferSize;

        // If we did not receive actual transfer size from network
        // stack, we prefer using Content-Length over resourceSize as
        // resourceSize may differ from actual transfer size if platform's
        // network stack performed decoding (e.g. gzip decompression).
        // The Content-Length, though, is expected to come from raw
        // response headers and will reflect actual transfer length.
        // This won't work for chunked content encoding, so fall back to
        // resourceSize when we don't have Content-Length. This still won't
        // work for chunks with non-trivial encodings. We need a way to
        // get actual transfer size from the network stack.

        return Number(this._responseHeaders.valueForCaseInsensitiveKey("Content-Length") || this._estimatedSize);
    }

    get estimatedTotalTransferSize()
    {
        let exact = this.networkTotalTransferSize;
        if (!isNaN(exact))
            return exact;

        if (this.statusCode === 304) // Not modified
            return this._estimatedResponseHeadersSize;

        if (this._cached)
            return 0;

        return this._estimatedResponseHeadersSize + this.estimatedNetworkEncodedSize;
    }

    get compressed()
    {
        let contentEncoding = this._responseHeaders.valueForCaseInsensitiveKey("Content-Encoding");
        return !!(contentEncoding && /\b(?:gzip|deflate|br)\b/.test(contentEncoding));
    }

    get requestedByteRange()
    {
        let range = this._requestHeaders.valueForCaseInsensitiveKey("Range");
        if (!range)
            return null;

        let rangeValues = range.match(/bytes=(\d+)-(\d+)/);
        if (!rangeValues)
            return null;

        let start = parseInt(rangeValues[1]);
        if (isNaN(start))
            return null;

        let end = parseInt(rangeValues[2]);
        if (isNaN(end))
            return null;

        return {start, end};
    }

    get scripts()
    {
        return this._scripts || [];
    }

    get serverTiming()
    {
        if (!this._serverTimingEntries)
            this._serverTimingEntries = WI.ServerTimingEntry.parseHeaders(this._responseHeaders.valueForCaseInsensitiveKey("Server-Timing"));
        return this._serverTimingEntries;
    }

    scriptForLocation(sourceCodeLocation)
    {
        console.assert(!(this instanceof WI.SourceMapResource));
        console.assert(sourceCodeLocation.sourceCode === this, "SourceCodeLocation must be in this Resource");
        if (sourceCodeLocation.sourceCode !== this)
            return null;

        var lineNumber = sourceCodeLocation.lineNumber;
        var columnNumber = sourceCodeLocation.columnNumber;
        for (var i = 0; i < this._scripts.length; ++i) {
            var script = this._scripts[i];
            if (script.range.startLine <= lineNumber && script.range.endLine >= lineNumber) {
                if (script.range.startLine === lineNumber && columnNumber < script.range.startColumn)
                    continue;
                if (script.range.endLine === lineNumber && columnNumber > script.range.endColumn)
                    continue;
                return script;
            }
        }

        return null;
    }

    updateForRedirectResponse(request, response, elapsedTime, walltime)
    {
        console.assert(!this._finished);
        console.assert(!this._failed);
        console.assert(!this._canceled);

        let oldURL = this._url;
        let oldHeaders = this._requestHeaders;

        if (request.url)
            this._url = request.url;

        this._requestHeaders = request.headers || {};
        this._requestCookies = null;
        this._redirects.push(new WI.Redirect(oldURL, request.method, oldHeaders, response.status, response.statusText, response.headers, elapsedTime));

        if (oldURL !== request.url) {
            // Delete the URL components so the URL is re-parsed the next time it is requested.
            this._urlComponents = null;

            this.dispatchEventToListeners(WI.Resource.Event.URLDidChange, {oldURL});
        }

        this.dispatchEventToListeners(WI.Resource.Event.RequestHeadersDidChange);
        this.dispatchEventToListeners(WI.Resource.Event.TimestampsDidChange);
    }

    hasResponse()
    {
        return !isNaN(this._statusCode) || this._finished || this._failed;
    }

    hasRequestFormParameters()
    {
        let requestDataContentType = this.requestDataContentType;
        return requestDataContentType && requestDataContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i);
    }

    updateForResponse(url, mimeType, type, responseHeaders, statusCode, statusText, elapsedTime, timingData, source, security)
    {
        console.assert(!this._finished);
        console.assert(!this._failed);
        console.assert(!this._canceled);

        let oldURL = this._url;
        let oldMIMEType = this._mimeType;
        let oldType = this._type;

        if (type in WI.Resource.Type)
            type = WI.Resource.Type[type];

        if (url)
            this._url = url;

        this._mimeType = mimeType;
        this._type = Resource.resolvedType(type, mimeType);
        this._statusCode = statusCode;
        this._statusText = statusText;
        this._responseHeaders = responseHeaders || {};
        this._responseCookies = null;
        this._serverTimingEntries = null;
        this._responseReceivedTimestamp = elapsedTime || NaN;
        this._timingData = WI.ResourceTimingData.fromPayload(timingData, this);

        if (source)
            this._responseSource = WI.Resource.responseSourceFromPayload(source);

        this._security = security || {};

        const headerBaseSize = 12; // Length of "HTTP/1.1 ", " ", and "\r\n".
        const headerPad = 4; // Length of ": " and "\r\n".
        this._estimatedResponseHeadersSize = String(this._statusCode).length + this._statusText.length + headerBaseSize;
        for (let name in this._responseHeaders)
            this._estimatedResponseHeadersSize += name.length + this._responseHeaders[name].length + headerPad;

        if (!this._cached) {
            if (statusCode === 304 || (this._responseSource === WI.Resource.ResponseSource.MemoryCache || this._responseSource === WI.Resource.ResponseSource.DiskCache))
                this.markAsCached();
        }

        if (oldURL !== url) {
            // Delete the URL components so the URL is re-parsed the next time it is requested.
            this._urlComponents = null;

            this.dispatchEventToListeners(WI.Resource.Event.URLDidChange, {oldURL});
        }

        if (oldMIMEType !== mimeType) {
            // Delete the MIME-type components so the MIME-type is re-parsed the next time it is requested.
            this._mimeTypeComponents = null;

            this.dispatchEventToListeners(WI.Resource.Event.MIMETypeDidChange, {oldMIMEType});
        }

        if (oldType !== type)
            this.dispatchEventToListeners(WI.Resource.Event.TypeDidChange, {oldType});

        console.assert(isNaN(this._estimatedSize));
        console.assert(isNaN(this._estimatedTransferSize));

        // The transferSize becomes 0 when status is 304 or Content-Length is available, so
        // notify listeners of that change.
        if (statusCode === 304 || this._responseHeaders.valueForCaseInsensitiveKey("Content-Length"))
            this.dispatchEventToListeners(WI.Resource.Event.TransferSizeDidChange);

        this.dispatchEventToListeners(WI.Resource.Event.ResponseReceived);
        this.dispatchEventToListeners(WI.Resource.Event.TimestampsDidChange);
    }

    updateWithMetrics(metrics)
    {
        this._receivedNetworkLoadMetrics = true;

        if (metrics.protocol)
            this._protocol = metrics.protocol;
        if (metrics.priority)
            this._priority = WI.Resource.networkPriorityFromPayload(metrics.priority);
        if (metrics.remoteAddress)
            this._remoteAddress = metrics.remoteAddress;
        if (metrics.connectionIdentifier)
            this._connectionIdentifier = WI.Resource.connectionIdentifierFromPayload(metrics.connectionIdentifier);
        if (metrics.requestHeaders) {
            this._requestHeaders = metrics.requestHeaders;
            this._requestCookies = null;
            this.dispatchEventToListeners(WI.Resource.Event.RequestHeadersDidChange);
        }

        if ("requestHeaderBytesSent" in metrics) {
            this._requestHeadersTransferSize = metrics.requestHeaderBytesSent;
            this._requestBodyTransferSize = metrics.requestBodyBytesSent;
            this._responseHeadersTransferSize = metrics.responseHeaderBytesReceived;
            this._responseBodyTransferSize = metrics.responseBodyBytesReceived;
            this._responseBodySize = metrics.responseBodyDecodedSize;

            console.assert(this._requestHeadersTransferSize >= 0);
            console.assert(this._requestBodyTransferSize >= 0);
            console.assert(this._responseHeadersTransferSize >= 0);
            console.assert(this._responseBodyTransferSize >= 0);
            console.assert(this._responseBodySize >= 0);

            // There may have been no size updates received during load if Content-Length was 0.
            if (isNaN(this._estimatedSize))
                this._estimatedSize = 0;

            this.dispatchEventToListeners(WI.Resource.Event.SizeDidChange, {previousSize: this._estimatedSize});
            this.dispatchEventToListeners(WI.Resource.Event.TransferSizeDidChange);
        }

        if (metrics.securityConnection) {
            if (!this._security)
                this._security = {};
            this._security.connection = metrics.securityConnection;
        }

        this.dispatchEventToListeners(WI.Resource.Event.MetricsDidChange);
    }

    setCachedResponseBodySize(size)
    {
        console.assert(!isNaN(size), "Size should be a valid number.");
        console.assert(isNaN(this._cachedResponseBodySize), "This should only be set once.");
        console.assert(this._estimatedSize === size, "The legacy path was updated already and matches.");

        this._cachedResponseBodySize = size;
    }

    requestContentFromBackend()
    {
        let specialContentPromise = WI.SourceCode.generateSpecialContentForURL(this._url);
        if (specialContentPromise)
            return specialContentPromise;

        // If we have the requestIdentifier we can get the actual response for this specific resource.
        // Otherwise the content will be cached resource data, which might not exist anymore.
        if (this._requestIdentifier)
            return NetworkAgent.getResponseBody(this._requestIdentifier);

        // There is no request identifier or frame to request content from.
        if (this._parentFrame)
            return PageAgent.getResourceContent(this._parentFrame.id, this._url);

        return Promise.reject(new Error("Content request failed."));
    }

    increaseSize(dataLength, elapsedTime)
    {
        console.assert(dataLength >= 0);
        console.assert(!this._receivedNetworkLoadMetrics, "If we received metrics we don't need to change the estimated size.");

        if (isNaN(this._estimatedSize))
            this._estimatedSize = 0;

        let previousSize = this._estimatedSize;

        this._estimatedSize += dataLength;

        this._lastDataReceivedTimestamp = elapsedTime || NaN;

        this.dispatchEventToListeners(WI.Resource.Event.SizeDidChange, {previousSize});

        // The estimatedTransferSize is based off of size when status is not 304 or Content-Length is missing.
        if (isNaN(this._estimatedTransferSize) && this._statusCode !== 304 && !this._responseHeaders.valueForCaseInsensitiveKey("Content-Length"))
            this.dispatchEventToListeners(WI.Resource.Event.TransferSizeDidChange);
    }

    increaseTransferSize(encodedDataLength)
    {
        console.assert(encodedDataLength >= 0);
        console.assert(!this._receivedNetworkLoadMetrics, "If we received metrics we don't need to change the estimated transfer size.");

        if (isNaN(this._estimatedTransferSize))
            this._estimatedTransferSize = 0;
        this._estimatedTransferSize += encodedDataLength;

        this.dispatchEventToListeners(WI.Resource.Event.TransferSizeDidChange);
    }

    markAsCached()
    {
        this._cached = true;

        this.dispatchEventToListeners(WI.Resource.Event.CacheStatusDidChange);

        // The transferSize starts returning 0 when cached is true, unless status is 304.
        if (this._statusCode !== 304)
            this.dispatchEventToListeners(WI.Resource.Event.TransferSizeDidChange);
    }

    markAsFinished(elapsedTime)
    {
        console.assert(!this._failed);
        console.assert(!this._canceled);

        this._finished = true;
        this._finishedOrFailedTimestamp = elapsedTime || NaN;
        this._timingData.markResponseEndTime(elapsedTime || NaN);

        if (this._finishThenRequestContentPromise)
            this._finishThenRequestContentPromise = null;

        this.dispatchEventToListeners(WI.Resource.Event.LoadingDidFinish);
        this.dispatchEventToListeners(WI.Resource.Event.TimestampsDidChange);
    }

    markAsFailed(canceled, elapsedTime, errorText)
    {
        console.assert(!this._finished);

        this._failed = true;
        this._canceled = canceled;
        this._finishedOrFailedTimestamp = elapsedTime || NaN;

        if (!this._failureReasonText)
            this._failureReasonText = errorText || null;

        this.dispatchEventToListeners(WI.Resource.Event.LoadingDidFail);
        this.dispatchEventToListeners(WI.Resource.Event.TimestampsDidChange);
    }

    revertMarkAsFinished()
    {
        console.assert(!this._failed);
        console.assert(!this._canceled);
        console.assert(this._finished);

        this._finished = false;
        this._finishedOrFailedTimestamp = NaN;
    }

    legacyMarkServedFromMemoryCache()
    {
        // COMPATIBILITY (iOS 10.3): This is a legacy code path where we know the resource came from the MemoryCache.
        console.assert(this._responseSource === WI.Resource.ResponseSource.Unknown);

        this._responseSource = WI.Resource.ResponseSource.MemoryCache;

        this.markAsCached();
    }

    legacyMarkServedFromDiskCache()
    {
        // COMPATIBILITY (iOS 10.3): This is a legacy code path where we know the resource came from the DiskCache.
        console.assert(this._responseSource === WI.Resource.ResponseSource.Unknown);

        this._responseSource = WI.Resource.ResponseSource.DiskCache;

        this.markAsCached();
    }

    isLoading()
    {
        return !this._finished && !this._failed;
    }

    hadLoadingError()
    {
        return this._failed || this._canceled || this._statusCode >= 400;
    }

    getImageSize(callback)
    {
        // Throw an error in the case this resource is not an image.
        if (this.type !== WI.Resource.Type.Image)
            throw "Resource is not an image.";

        // See if we've already computed and cached the image size,
        // in which case we can provide them directly.
        if (this._imageSize !== undefined) {
            callback(this._imageSize);
            return;
        }

        var objectURL = null;

        // Event handler for the image "load" event.
        function imageDidLoad() {
            URL.revokeObjectURL(objectURL);

            // Cache the image metrics.
            this._imageSize = {
                width: image.width,
                height: image.height
            };

            callback(this._imageSize);
        }

        function requestContentFailure() {
            this._imageSize = null;
            callback(this._imageSize);
        }

        // Create an <img> element that we'll use to load the image resource
        // so that we can query its intrinsic size.
        var image = new Image;
        image.addEventListener("load", imageDidLoad.bind(this), false);

        // Set the image source using an object URL once we've obtained its data.
        this.requestContent().then((content) => {
            objectURL = image.src = content.sourceCode.createObjectURL();
            if (!objectURL)
                requestContentFailure.call(this);
        }, requestContentFailure.bind(this));
    }

    requestContent()
    {
        if (this._finished)
            return super.requestContent();

        if (this._failed)
            return Promise.resolve({error: WI.UIString("An error occurred trying to load the resource.")});

        if (!this._finishThenRequestContentPromise) {
            this._finishThenRequestContentPromise = new Promise((resolve, reject) => {
                this.addEventListener(WI.Resource.Event.LoadingDidFinish, resolve);
                this.addEventListener(WI.Resource.Event.LoadingDidFail, reject);
            }).then(WI.SourceCode.prototype.requestContent.bind(this));
        }

        return this._finishThenRequestContentPromise;
    }

    associateWithScript(script)
    {
        if (!this._scripts)
            this._scripts = [];

        this._scripts.push(script);

        if (this._type === WI.Resource.Type.Other || this._type === WI.Resource.Type.XHR) {
            let oldType = this._type;
            this._type = WI.Resource.Type.Script;
            this.dispatchEventToListeners(WI.Resource.Event.TypeDidChange, {oldType});
        }
    }

    saveIdentityToCookie(cookie)
    {
        cookie[WI.Resource.URLCookieKey] = this.url.hash;
        cookie[WI.Resource.MainResourceCookieKey] = this.isMainResource();
    }

    async createLocalResourceOverride({initialContent} = {})
    {
        console.assert(!this.isLocalResourceOverride);
        console.assert(WI.NetworkManager.supportsLocalResourceOverrides());

        let {rawContent, rawBase64Encoded} = await this.requestContent();
        let content = initialContent !== undefined ? initialContent : rawContent;

        return WI.LocalResourceOverride.create({
            url: this.url,
            mimeType: this.mimeType,
            content,
            base64Encoded: rawBase64Encoded,
            statusCode: this.statusCode,
            statusText: this.statusText,
            headers: this.responseHeaders,
        });
    }

    generateCURLCommand()
    {
        function escapeStringPosix(str) {
            function escapeCharacter(x) {
                let code = x.charCodeAt(0);
                let hex = code.toString(16);
                if (code < 256)
                    return "\\x" + hex.padStart(2, "0");
                return "\\u" + hex.padStart(4, "0");
            }

            if (/[^\x20-\x7E]|'/.test(str)) {
                // Use ANSI-C quoting syntax.
                return "$'" + str.replace(/\\/g, "\\\\")
                                 .replace(/'/g, "\\'")
                                 .replace(/\n/g, "\\n")
                                 .replace(/\r/g, "\\r")
                                 .replace(/!/g, "\\041")
                                 .replace(/[^\x20-\x7E]/g, escapeCharacter) + "'";
            } else {
                // Use single quote syntax.
                return `'${str}'`;
            }
        }

        let command = ["curl " + escapeStringPosix(this.url).replace(/[[{}\]]/g, "\\$&")];
        command.push(`-X${this.requestMethod}`);

        for (let key in this.requestHeaders)
            command.push("-H " + escapeStringPosix(`${key}: ${this.requestHeaders[key]}`));

        if (this.requestDataContentType && this.requestMethod !== "GET" && this.requestData) {
            if (this.requestDataContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
                command.push("--data " + escapeStringPosix(this.requestData));
            else
                command.push("--data-binary " + escapeStringPosix(this.requestData));
        }

        return command.join(" \\\n");
    }

    stringifyHTTPRequest()
    {
        let lines = [];

        let protocol = this.protocol || "";
        if (protocol === "h2") {
            // HTTP/2 Request pseudo headers:
            // https://tools.ietf.org/html/rfc7540#section-8.1.2.3
            lines.push(`:method: ${this.requestMethod}`);
            lines.push(`:scheme: ${this.urlComponents.scheme}`);
            lines.push(`:authority: ${WI.h2Authority(this.urlComponents)}`);
            lines.push(`:path: ${WI.h2Path(this.urlComponents)}`);
        } else {
            // HTTP/1.1 request line:
            // https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1
            lines.push(`${this.requestMethod} ${this.urlComponents.path}${protocol ? " " + protocol.toUpperCase() : ""}`);
        }

        for (let key in this.requestHeaders)
            lines.push(`${key}: ${this.requestHeaders[key]}`);

        return lines.join("\n") + "\n";
    }

    stringifyHTTPResponse()
    {
        let lines = [];

        let protocol = this.protocol || "";
        if (protocol === "h2") {
            // HTTP/2 Response pseudo headers:
            // https://tools.ietf.org/html/rfc7540#section-8.1.2.4
            lines.push(`:status: ${this.statusCode}`);
        } else {
            // HTTP/1.1 response status line:
            // https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1
            lines.push(`${protocol ? protocol.toUpperCase() + " " : ""}${this.statusCode} ${this.statusText}`);
        }

        for (let key in this.responseHeaders)
            lines.push(`${key}: ${this.responseHeaders[key]}`);

        return lines.join("\n") + "\n";
    }

    async showCertificate()
    {
        let errorString = WI.UIString("Unable to show certificate for \u201C%s\u201D").format(this.url);

        try {
            let {serializedCertificate} = await NetworkAgent.getSerializedCertificate(this._requestIdentifier);
            if (InspectorFrontendHost.showCertificate(serializedCertificate))
                return;
        } catch (e) {
            console.error(e);
            throw errorString;
        }

        let consoleMessage = new WI.ConsoleMessage(this._target, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, errorString);
        consoleMessage.shouldRevealConsole = true;
        WI.consoleLogViewController.appendConsoleMessage(consoleMessage);

        throw errorString;
    }
};

WI.Resource.TypeIdentifier = "resource";
WI.Resource.URLCookieKey = "resource-url";
WI.Resource.MainResourceCookieKey = "resource-is-main-resource";

WI.Resource.Event = {
    URLDidChange: "resource-url-did-change",
    MIMETypeDidChange: "resource-mime-type-did-change",
    TypeDidChange: "resource-type-did-change",
    RequestHeadersDidChange: "resource-request-headers-did-change",
    ResponseReceived: "resource-response-received",
    LoadingDidFinish: "resource-loading-did-finish",
    LoadingDidFail: "resource-loading-did-fail",
    TimestampsDidChange: "resource-timestamps-did-change",
    SizeDidChange: "resource-size-did-change",
    TransferSizeDidChange: "resource-transfer-size-did-change",
    CacheStatusDidChange: "resource-cached-did-change",
    MetricsDidChange: "resource-metrics-did-change",
    InitiatedResourcesDidChange: "resource-initiated-resources-did-change",
};

// Keep these in sync with the "ResourceType" enum defined by the "Page" domain.
WI.Resource.Type = {
    Document: "resource-type-document",
    StyleSheet: "resource-type-style-sheet",
    Image: "resource-type-image",
    Font: "resource-type-font",
    Script: "resource-type-script",
    XHR: "resource-type-xhr",
    Fetch: "resource-type-fetch",
    Ping: "resource-type-ping",
    Beacon: "resource-type-beacon",
    WebSocket: "resource-type-websocket",
    Other: "resource-type-other",

    // COMPATIBILITY (iOS 13): Page.ResourceType.Stylesheet was renamed to Page.ResourceType.StyleSheet.
    Stylesheet: "resource-type-style-sheet",
};

WI.Resource.ResponseSource = {
    Unknown: Symbol("unknown"),
    Network: Symbol("network"),
    MemoryCache: Symbol("memory-cache"),
    DiskCache: Symbol("disk-cache"),
    ServiceWorker: Symbol("service-worker"),
    InspectorOverride: Symbol("inspector-override"),
};

WI.Resource.NetworkPriority = {
    Unknown: Symbol("unknown"),
    Low: Symbol("low"),
    Medium: Symbol("medium"),
    High: Symbol("high"),
};

WI.Resource.GroupingMode = {
    Path: "group-resource-by-path",
    Type: "group-resource-by-type",
};
WI.settings.resourceGroupingMode = new WI.Setting("resource-grouping-mode", WI.Resource.GroupingMode.Type);

// This MIME Type map is private, use WI.Resource.typeFromMIMEType().
WI.Resource._mimeTypeMap = {
    "text/html": WI.Resource.Type.Document,
    "text/xml": WI.Resource.Type.Document,
    "application/xhtml+xml": WI.Resource.Type.Document,

    "text/plain": WI.Resource.Type.Other,

    "text/css": WI.Resource.Type.StyleSheet,
    "text/xsl": WI.Resource.Type.StyleSheet,
    "text/x-less": WI.Resource.Type.StyleSheet,
    "text/x-sass": WI.Resource.Type.StyleSheet,
    "text/x-scss": WI.Resource.Type.StyleSheet,

    "application/pdf": WI.Resource.Type.Image,
    "image/svg+xml": WI.Resource.Type.Image,

    "application/x-font-type1": WI.Resource.Type.Font,
    "application/x-font-ttf": WI.Resource.Type.Font,
    "application/x-font-woff": WI.Resource.Type.Font,
    "application/x-truetype-font": WI.Resource.Type.Font,

    "text/javascript": WI.Resource.Type.Script,
    "text/ecmascript": WI.Resource.Type.Script,
    "application/javascript": WI.Resource.Type.Script,
    "application/ecmascript": WI.Resource.Type.Script,
    "application/x-javascript": WI.Resource.Type.Script,
    "application/json": WI.Resource.Type.Script,
    "application/x-json": WI.Resource.Type.Script,
    "text/x-javascript": WI.Resource.Type.Script,
    "text/x-json": WI.Resource.Type.Script,
    "text/javascript1.1": WI.Resource.Type.Script,
    "text/javascript1.2": WI.Resource.Type.Script,
    "text/javascript1.3": WI.Resource.Type.Script,
    "text/jscript": WI.Resource.Type.Script,
    "text/livescript": WI.Resource.Type.Script,
    "text/x-livescript": WI.Resource.Type.Script,
    "text/typescript": WI.Resource.Type.Script,
    "text/typescript-jsx": WI.Resource.Type.Script,
    "text/jsx": WI.Resource.Type.Script,
    "text/x-clojure": WI.Resource.Type.Script,
    "text/x-coffeescript": WI.Resource.Type.Script,
};
