/*
 * 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.NetworkManager = function()
{
    WebInspector.Object.call(this);
    this._dispatcher = new WebInspector.NetworkDispatcher(this);
    if (WebInspector.settings.cacheDisabled.get())
        NetworkAgent.setCacheDisabled(true);

    NetworkAgent.enable();

    WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
}

WebInspector.NetworkManager.EventTypes = {
    RequestStarted: "RequestStarted",
    RequestUpdated: "RequestUpdated",
    RequestFinished: "RequestFinished",
    RequestUpdateDropped: "RequestUpdateDropped"
}

WebInspector.NetworkManager._MIMETypes = {
    "text/html":                   {"document": true},
    "text/xml":                    {"document": true},
    "text/plain":                  {"document": true},
    "application/xhtml+xml":       {"document": true},
    "text/css":                    {"stylesheet": true},
    "text/xsl":                    {"stylesheet": true},
    "image/jpg":                   {"image": true},
    "image/jpeg":                  {"image": true},
    "image/pjpeg":                 {"image": true},
    "image/png":                   {"image": true},
    "image/gif":                   {"image": true},
    "image/bmp":                   {"image": true},
    "image/svg+xml":               {"image": true, "font": true, "document": true},
    "image/vnd.microsoft.icon":    {"image": true},
    "image/webp":                  {"image": true},
    "image/x-icon":                {"image": true},
    "image/x-xbitmap":             {"image": true},
    "font/ttf":                    {"font": true},
    "font/otf":                    {"font": true},
    "font/woff":                   {"font": true},
    "font/woff2":                  {"font": true},
    "font/truetype":               {"font": true},
    "font/opentype":               {"font": true},
    "application/octet-stream":    {"font": true, "image": true},
    "application/font-woff":       {"font": true},
    "application/x-font-woff":     {"font": true},
    "application/x-font-type1":    {"font": true},
    "application/x-font-ttf":      {"font": true},
    "application/x-truetype-font": {"font": true},
    "text/javascript":             {"script": true},
    "text/ecmascript":             {"script": true},
    "application/javascript":      {"script": true},
    "application/ecmascript":      {"script": true},
    "application/x-javascript":    {"script": true},
    "application/json":            {"script": true},
    "text/javascript1.1":          {"script": true},
    "text/javascript1.2":          {"script": true},
    "text/javascript1.3":          {"script": true},
    "text/jscript":                {"script": true},
    "text/livescript":             {"script": true},
}

WebInspector.NetworkManager.prototype = {
    /**
     * @param {string} url
     * @return {WebInspector.NetworkRequest}
     */
    inflightRequestForURL: function(url)
    {
        return this._dispatcher._inflightRequestsByURL[url];
    },

    /**
     * @param {WebInspector.Event} event
     */
    _cacheDisabledSettingChanged: function(event)
    {
        var enabled = /** @type {boolean} */ (event.data);
        NetworkAgent.setCacheDisabled(enabled);
    },

    __proto__: WebInspector.Object.prototype
}

/**
 * @constructor
 * @implements {NetworkAgent.Dispatcher}
 */
WebInspector.NetworkDispatcher = function(manager)
{
    this._manager = manager;
    this._inflightRequestsById = {};
    this._inflightRequestsByURL = {};
    InspectorBackend.registerNetworkDispatcher(this);
}

WebInspector.NetworkDispatcher.prototype = {
    /**
     * @param {NetworkAgent.Headers} headersMap
     * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
     */
    _headersMapToHeadersArray: function(headersMap)
    {
        var result = [];
        for (var name in headersMap) {
            var values = headersMap[name].split("\n");
            for (var i = 0; i < values.length; ++i)
                result.push({name: name, value: values[i]});
        }
        return result;
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     * @param {NetworkAgent.Request} request
     */
    _updateNetworkRequestWithRequest: function(networkRequest, request)
    {
        networkRequest.requestMethod = request.method;
        networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
        networkRequest.requestFormData = request.postData;
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     * @param {NetworkAgent.Response=} response
     */
    _updateNetworkRequestWithResponse: function(networkRequest, response)
    {
        if (!response)
            return;

        if (response.url && networkRequest.url !== response.url)
            networkRequest.url = response.url;
        networkRequest.mimeType = response.mimeType;
        networkRequest.statusCode = response.status;
        networkRequest.statusText = response.statusText;
        networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
        if (response.headersText)
            networkRequest.responseHeadersText = response.headersText;
        if (response.requestHeaders)
            networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
        if (response.requestHeadersText)
            networkRequest.requestHeadersText = response.requestHeadersText;

        networkRequest.connectionReused = response.connectionReused;
        networkRequest.connectionId = response.connectionId;

        if (response.fromDiskCache)
            networkRequest.cached = true;
        else
            networkRequest.timing = response.timing;

        if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
            WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
                WebInspector.ConsoleMessage.MessageLevel.Log,
                WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
                WebInspector.ConsoleMessage.MessageType.Log,
                "",
                0,
                0,
                1,
                [],
                null,
                networkRequest.requestId));
        }
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     * @return {boolean}
     */
    _mimeTypeIsConsistentWithType: function(networkRequest)
    {
        // If status is an error, content is likely to be of an inconsistent type,
        // as it's going to be an error message. We do not want to emit a warning
        // for this, though, as this will already be reported as resource loading failure.
        // Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,
        // it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.
        // Don't check for mime-types in 304-resources.
        if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
            return true;

        if (typeof networkRequest.type === "undefined"
            || networkRequest.type === WebInspector.resourceTypes.Other
            || networkRequest.type === WebInspector.resourceTypes.XHR
            || networkRequest.type === WebInspector.resourceTypes.WebSocket)
            return true;

        if (!networkRequest.mimeType)
            return true; // Might be not known for cached resources with null responses.

        if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
            return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];

        return false;
    },

    /**
     * @param {NetworkAgent.Response} response
     * @return {boolean}
     */
    _isNull: function(response)
    {
        if (!response)
            return true;
        return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {PageAgent.FrameId} frameId
     * @param {NetworkAgent.LoaderId} loaderId
     * @param {string} documentURL
     * @param {NetworkAgent.Request} request
     * @param {NetworkAgent.Timestamp} time
     * @param {NetworkAgent.Initiator} initiator
     * @param {NetworkAgent.Response=} redirectResponse
     */
    requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (networkRequest) {
            // FIXME: move this check to the backend.
            if (!redirectResponse)
                return;
            this.responseReceived(requestId, frameId, loaderId, time, PageAgent.ResourceType.Other, redirectResponse);
            networkRequest = this._appendRedirect(requestId, time, request.url);
        } else
            networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
        networkRequest.hasNetworkData = true;
        this._updateNetworkRequestWithRequest(networkRequest, request);
        networkRequest.startTime = time;

        this._startNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     */
    requestServedFromCache: function(requestId)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.cached = true;
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {PageAgent.FrameId} frameId
     * @param {NetworkAgent.LoaderId} loaderId
     * @param {NetworkAgent.Timestamp} time
     * @param {PageAgent.ResourceType} resourceType
     * @param {NetworkAgent.Response} response
     */
    responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
    {
        // FIXME: move this check to the backend.
        if (this._isNull(response))
            return;

        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest) {
            // We missed the requestWillBeSent.
            var eventData = {};
            eventData.url = response.url;
            eventData.frameId = frameId;
            eventData.loaderId = loaderId;
            eventData.resourceType = resourceType;
            eventData.mimeType = response.mimeType;
            this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
            return;
        }

        networkRequest.responseReceivedTime = time;
        networkRequest.type = WebInspector.resourceTypes[resourceType];

        this._updateNetworkRequestWithResponse(networkRequest, response);

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {number} dataLength
     * @param {number} encodedDataLength
     */
    dataReceived: function(requestId, time, dataLength, encodedDataLength)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.resourceSize += dataLength;
        if (encodedDataLength != -1)
            networkRequest.increaseTransferSize(encodedDataLength);
        networkRequest.endTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} finishTime
     */
    loadingFinished: function(requestId, finishTime)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;
        this._finishNetworkRequest(networkRequest, finishTime);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {string} localizedDescription
     * @param {boolean=} canceled
     */
    loadingFailed: function(requestId, time, localizedDescription, canceled)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.failed = true;
        networkRequest.canceled = canceled;
        networkRequest.localizedFailDescription = localizedDescription;
        this._finishNetworkRequest(networkRequest, time);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {string} requestURL
     */
    webSocketCreated: function(requestId, requestURL)
    {
        var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
        networkRequest.type = WebInspector.resourceTypes.WebSocket;
        this._startNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {NetworkAgent.WebSocketRequest} request
     */
    webSocketWillSendHandshakeRequest: function(requestId, time, request)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.requestMethod = "GET";
        networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
        networkRequest.startTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {NetworkAgent.WebSocketResponse} response
     */
    webSocketHandshakeResponseReceived: function(requestId, time, response)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.statusCode = response.status;
        networkRequest.statusText = response.statusText;
        networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
        networkRequest.responseReceivedTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {NetworkAgent.WebSocketFrame} response
     */
    webSocketFrameReceived: function(requestId, time, response)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.addFrame(response, time);
        networkRequest.responseReceivedTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {NetworkAgent.WebSocketFrame} response
     */
    webSocketFrameSent: function(requestId, time, response)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.addFrame(response, time, true);
        networkRequest.responseReceivedTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {string} errorMessage
     */
    webSocketFrameError: function(requestId, time, errorMessage)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;

        networkRequest.addFrameError(errorMessage, time);
        networkRequest.responseReceivedTime = time;

        this._updateNetworkRequest(networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     */
    webSocketClosed: function(requestId, time)
    {
        var networkRequest = this._inflightRequestsById[requestId];
        if (!networkRequest)
            return;
        this._finishNetworkRequest(networkRequest, time);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {NetworkAgent.Timestamp} time
     * @param {string} redirectURL
     * @return {WebInspector.NetworkRequest}
     */
    _appendRedirect: function(requestId, time, redirectURL)
    {
        var originalNetworkRequest = this._inflightRequestsById[requestId];
        var previousRedirects = originalNetworkRequest.redirects || [];
        originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
        delete originalNetworkRequest.redirects;
        if (previousRedirects.length > 0)
            originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
        this._finishNetworkRequest(originalNetworkRequest, time);
        var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
             redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
        newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
        return newNetworkRequest;
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     */
    _startNetworkRequest: function(networkRequest)
    {
        this._inflightRequestsById[networkRequest.requestId] = networkRequest;
        this._inflightRequestsByURL[networkRequest.url] = networkRequest;
        this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     */
    _updateNetworkRequest: function(networkRequest)
    {
        this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
    },

    /**
     * @param {WebInspector.NetworkRequest} networkRequest
     * @param {NetworkAgent.Timestamp} finishTime
     */
    _finishNetworkRequest: function(networkRequest, finishTime)
    {
        networkRequest.endTime = finishTime;
        networkRequest.finished = true;
        this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
        delete this._inflightRequestsById[networkRequest.requestId];
        delete this._inflightRequestsByURL[networkRequest.url];
    },

    /**
     * @param {string} eventType
     * @param {WebInspector.NetworkRequest} networkRequest
     */
    _dispatchEventToListeners: function(eventType, networkRequest)
    {
        this._manager.dispatchEventToListeners(eventType, networkRequest);
    },

    /**
     * @param {NetworkAgent.RequestId} requestId
     * @param {string} frameId
     * @param {NetworkAgent.LoaderId} loaderId
     * @param {string} url
     * @param {string} documentURL
     * @param {NetworkAgent.Initiator} initiator
     */
    _createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
    {
        var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
        networkRequest.initiator = initiator;
        return networkRequest;
    }
}

/**
 * @type {?WebInspector.NetworkManager}
 */
WebInspector.networkManager = null;
