/*
 * Copyright (C) 2007, 2008 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. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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.
 */
WebInspector.Resource = function(identifier, url)
{
    this.identifier = identifier;
    this.url = url;
    this._startTime = -1;
    this._endTime = -1;
    this._category = WebInspector.resourceCategories.other;
    this._pendingContentCallbacks = [];
    this.history = [];
}

// Keep these in sync with WebCore::InspectorResource::Type
WebInspector.Resource.Type = {
    Document:   0,
    Stylesheet: 1,
    Image:      2,
    Font:       3,
    Script:     4,
    XHR:        5,
    WebSocket:  7,
    Other:      8,

    isTextType: function(type)
    {
        return (type === this.Document) || (type === this.Stylesheet) || (type === this.Script) || (type === this.XHR);
    },

    toUIString: function(type)
    {
        switch (type) {
            case this.Document:
                return WebInspector.UIString("Document");
            case this.Stylesheet:
                return WebInspector.UIString("Stylesheet");
            case this.Image:
                return WebInspector.UIString("Image");
            case this.Font:
                return WebInspector.UIString("Font");
            case this.Script:
                return WebInspector.UIString("Script");
            case this.XHR:
                return WebInspector.UIString("XHR");
            case this.WebSocket:
                return WebInspector.UIString("WebSocket");
            case this.Other:
            default:
                return WebInspector.UIString("Other");
        }
    },

    // Returns locale-independent string identifier of resource type (primarily for use in extension API).
    // The IDs need to be kept in sync with webInspector.resoureces.Types object in ExtensionAPI.js.
    toString: function(type)
    {
        switch (type) {
            case this.Document:
                return "document";
            case this.Stylesheet:
                return "stylesheet";
            case this.Image:
                return "image";
            case this.Font:
                return "font";
            case this.Script:
                return "script";
            case this.XHR:
                return "xhr";
            case this.WebSocket:
                return "websocket";
            case this.Other:
            default:
                return "other";
        }
    }
}

WebInspector.Resource._domainModelBindings = [];

WebInspector.Resource.registerDomainModelBinding = function(type, binding)
{
    WebInspector.Resource._domainModelBindings[type] = binding;
}

WebInspector.Resource.Events = {
    RevisionAdded: 0
}

WebInspector.Resource.prototype = {
    get url()
    {
        return this._url;
    },

    set url(x)
    {
        if (this._url === x)
            return;

        this._url = x;
        delete this._parsedQueryParameters;

        var parsedURL = x.asParsedURL();
        this.domain = parsedURL ? parsedURL.host : "";
        this.path = parsedURL ? parsedURL.path : "";
        this.lastPathComponent = "";
        if (parsedURL && parsedURL.path) {
            // First cut the query params.
            var path = parsedURL.path;
            var indexOfQuery = path.indexOf("?");
            if (indexOfQuery !== -1)
                path = path.substring(0, indexOfQuery);

            // Then take last path component.
            var lastSlashIndex = path.lastIndexOf("/");
            if (lastSlashIndex !== -1)
                this.lastPathComponent = path.substring(lastSlashIndex + 1);
        }
        this.lastPathComponentLowerCase = this.lastPathComponent.toLowerCase();
    },

    get documentURL()
    {
        return this._documentURL;
    },

    set documentURL(x)
    {
        this._documentURL = x;
    },

    get displayName()
    {
        if (this._displayName)
            return this._displayName;
        this._displayName = this.lastPathComponent;
        if (!this._displayName)
            this._displayName = this.displayDomain;
        if (!this._displayName && this.url)
            this._displayName = this.url.trimURL(WebInspector.mainResource ? WebInspector.mainResource.domain : "");
        if (this._displayName === "/")
            this._displayName = this.url;
        return this._displayName;
    },

    get displayDomain()
    {
        // WebInspector.Database calls this, so don't access more than this.domain.
        if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
            return this.domain;
        return "";
    },

    get startTime()
    {
        return this._startTime || -1;
    },

    set startTime(x)
    {
        this._startTime = x;
    },

    get responseReceivedTime()
    {
        return this._responseReceivedTime || -1;
    },

    set responseReceivedTime(x)
    {
        this._responseReceivedTime = x;
    },

    get endTime()
    {
        return this._endTime || -1;
    },

    set endTime(x)
    {
        if (this.timing && this.timing.requestTime) {
            // Check against accurate responseReceivedTime.
            this._endTime = Math.max(x, this.responseReceivedTime);
        } else {
            // Prefer endTime since it might be from the network stack.
            this._endTime = x;
            if (this._responseReceivedTime > x)
                this._responseReceivedTime = x;
        }
    },

    get duration()
    {
        if (this._endTime === -1 || this._startTime === -1)
            return -1;
        return this._endTime - this._startTime;
    },

    get latency()
    {
        if (this._responseReceivedTime === -1 || this._startTime === -1)
            return -1;
        return this._responseReceivedTime - this._startTime;
    },

    get receiveDuration()
    {
        if (this._endTime === -1 || this._responseReceivedTime === -1)
            return -1;
        return this._endTime - this._responseReceivedTime;
    },

    get resourceSize()
    {
        return this._resourceSize || 0;
    },

    set resourceSize(x)
    {
        this._resourceSize = x;
    },

    get transferSize()
    {
        if (this.cached)
            return 0;
        if (this.statusCode === 304) // Not modified
            return this.responseHeadersSize;
        if (this._transferSize !== undefined)
            return this._transferSize;
        // 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.
        var bodySize = Number(this.responseHeaders["Content-Length"] || this.resourceSize);
        return this.responseHeadersSize + bodySize;
    },

    increaseTransferSize: function(x)
    {
        this._transferSize = (this._transferSize || 0) + x;
    },

    get finished()
    {
        return this._finished;
    },

    set finished(x)
    {
        if (this._finished === x)
            return;

        this._finished = x;

        if (x) {
            this._checkWarnings();
            this.dispatchEventToListeners("finished");
            if (this._pendingContentCallbacks.length)
                this._innerRequestContent();
        }
    },

    get failed()
    {
        return this._failed;
    },

    set failed(x)
    {
        this._failed = x;
    },

    get canceled()
    {
        return this._canceled;
    },

    set canceled(x)
    {
        this._canceled = x;
    },

    get category()
    {
        return this._category;
    },

    set category(x)
    {
        this._category = x;
    },

    get cached()
    {
        return this._cached;
    },

    set cached(x)
    {
        this._cached = x;
        if (x)
            delete this._timing;
    },

    get timing()
    {
        return this._timing;
    },

    set timing(x)
    {
        if (x && !this._cached) {
            // Take startTime and responseReceivedTime from timing data for better accuracy.
            // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
            this._startTime = x.requestTime;
            this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;

            this._timing = x;
            this.dispatchEventToListeners("timing changed");
        }
    },

    get mimeType()
    {
        return this._mimeType;
    },

    set mimeType(x)
    {
        this._mimeType = x;
    },

    get type()
    {
        return this._type;
    },

    set type(x)
    {
        if (this._type === x)
            return;

        this._type = x;

        switch (x) {
            case WebInspector.Resource.Type.Document:
                this.category = WebInspector.resourceCategories.documents;
                break;
            case WebInspector.Resource.Type.Stylesheet:
                this.category = WebInspector.resourceCategories.stylesheets;
                break;
            case WebInspector.Resource.Type.Script:
                this.category = WebInspector.resourceCategories.scripts;
                break;
            case WebInspector.Resource.Type.Image:
                this.category = WebInspector.resourceCategories.images;
                break;
            case WebInspector.Resource.Type.Font:
                this.category = WebInspector.resourceCategories.fonts;
                break;
            case WebInspector.Resource.Type.XHR:
                this.category = WebInspector.resourceCategories.xhr;
                break;
            case WebInspector.Resource.Type.WebSocket:
                this.category = WebInspector.resourceCategories.websockets;
                break;
            case WebInspector.Resource.Type.Other:
            default:
                this.category = WebInspector.resourceCategories.other;
                break;
        }
    },

    get requestHeaders()
    {
        return this._requestHeaders || {};
    },

    set requestHeaders(x)
    {
        this._requestHeaders = x;
        delete this._sortedRequestHeaders;
        delete this._requestCookies;
        delete this._responseHeadersSize;

        this.dispatchEventToListeners("requestHeaders changed");
    },

    get requestHeadersText()
    {
        return this._requestHeadersText;
    },

    set requestHeadersText(x)
    {
        this._requestHeadersText = x;
        delete this._responseHeadersSize;

        this.dispatchEventToListeners("requestHeaders changed");
    },

    get requestHeadersSize()
    {
        if (typeof(this._requestHeadersSize) === "undefined") {
            if (this._requestHeadersText)
                this._requestHeadersSize = this._requestHeadersText.length;
            else 
                this._requestHeadersSize = this._headersSize(this._requestHeaders)
        }
        return this._requestHeadersSize;
    },

    get sortedRequestHeaders()
    {
        if (this._sortedRequestHeaders !== undefined)
            return this._sortedRequestHeaders;

        this._sortedRequestHeaders = [];
        for (var key in this.requestHeaders)
            this._sortedRequestHeaders.push({header: key, value: this.requestHeaders[key]});
        this._sortedRequestHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });

        return this._sortedRequestHeaders;
    },

    requestHeaderValue: function(headerName)
    {
        return this._headerValue(this.requestHeaders, headerName);
    },

    get requestCookies()
    {
        if (!this._requestCookies)
            this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
        return this._requestCookies;
    },

    get requestFormData()
    {
        return this._requestFormData;
    },

    set requestFormData(x)
    {
        this._requestFormData = x;
        delete this._parsedFormParameters;
    },

    get responseHeaders()
    {
        return this._responseHeaders || {};
    },

    set responseHeaders(x)
    {
        this._responseHeaders = x;
        delete this._responseHeadersSize;
        delete this._sortedResponseHeaders;
        delete this._responseCookies;

        this.dispatchEventToListeners("responseHeaders changed");
    },
    
    get responseHeadersText()
    {
        return this._responseHeadersText;
    },

    set responseHeadersText(x)
    {
        this._responseHeadersText = x;
        delete this._responseHeadersSize;

        this.dispatchEventToListeners("responseHeaders changed");
    },
    
    get responseHeadersSize()
    {
        if (typeof(this._responseHeadersSize) === "undefined") {
            if (this._responseHeadersText)
                this._responseHeadersSize = this._responseHeadersText.length;
            else 
                this._responseHeadersSize = this._headersSize(this._responseHeaders)
        }
        return this._responseHeadersSize;
    },
    

    get sortedResponseHeaders()
    {
        if (this._sortedResponseHeaders !== undefined)
            return this._sortedResponseHeaders;

        this._sortedResponseHeaders = [];
        for (var key in this.responseHeaders)
            this._sortedResponseHeaders.push({header: key, value: this.responseHeaders[key]});
        this._sortedResponseHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });

        return this._sortedResponseHeaders;
    },

    responseHeaderValue: function(headerName)
    {
        return this._headerValue(this.responseHeaders, headerName);
    },

    get responseCookies()
    {
        if (!this._responseCookies)
            this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
        return this._responseCookies;
    },

    get queryParameters()
    {
        if (this._parsedQueryParameters)
            return this._parsedQueryParameters;
        var queryString = this.url.split("?", 2)[1];
        if (!queryString)
            return;
        this._parsedQueryParameters = this._parseParameters(queryString);
        return this._parsedQueryParameters;
    },

    get formParameters()
    {
        if (this._parsedFormParameters)
            return this._parsedFormParameters;
        if (!this.requestFormData)
            return;
        var requestContentType = this.requestHeaderValue("Content-Type");
        if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
            return;
        this._parsedFormParameters = this._parseParameters(this.requestFormData);
        return this._parsedFormParameters;
    },

    _parseParameters: function(queryString)
    {
        function parseNameValue(pair)
        {
            var parameter = {};
            var splitPair = pair.split("=", 2);

            parameter.name = splitPair[0];
            if (splitPair.length === 1)
                parameter.value = "";
            else
                parameter.value = splitPair[1];
            return parameter;
        }
        return queryString.split("&").map(parseNameValue);
    },

    _headerValue: function(headers, headerName)
    {
        headerName = headerName.toLowerCase();
        for (var header in headers) {
            if (header.toLowerCase() === headerName)
                return headers[header];
        }
    },

    _headersSize: function(headers)
    {
        // We should take actual headers size from network stack, when possible, but fall back to
        // this lousy computation when no headers text is available.
        var size = 0;
        for (var header in headers)
            size += header.length + headers[header].length + 4; // _typical_ overhead per header is ": ".length + "\r\n".length.
        return size;
    },

    get errors()
    {
        return this._errors || 0;
    },

    set errors(x)
    {
        this._errors = x;
        this.dispatchEventToListeners("errors-warnings-updated");
    },

    get warnings()
    {
        return this._warnings || 0;
    },

    set warnings(x)
    {
        this._warnings = x;
        this.dispatchEventToListeners("errors-warnings-updated");
    },

    clearErrorsAndWarnings: function()
    {
        this._warnings = 0;
        this._errors = 0;
        this.dispatchEventToListeners("errors-warnings-updated");
    },

    _mimeTypeIsConsistentWithType: function()
    {
        // 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 (this.statusCode >= 400 || this.statusCode === 304)
            return true;

        if (typeof this.type === "undefined"
            || this.type === WebInspector.Resource.Type.Other
            || this.type === WebInspector.Resource.Type.XHR
            || this.type === WebInspector.Resource.Type.WebSocket)
            return true;

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

        if (this.mimeType in WebInspector.MIMETypes)
            return this.type in WebInspector.MIMETypes[this.mimeType];

        return false;
    },

    _checkWarnings: function()
    {
        for (var warning in WebInspector.Warnings)
            this._checkWarning(WebInspector.Warnings[warning]);
    },

    _checkWarning: function(warning)
    {
        var msg;
        switch (warning.id) {
            case WebInspector.Warnings.IncorrectMIMEType.id:
                if (!this._mimeTypeIsConsistentWithType())
                    msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
                        WebInspector.ConsoleMessage.MessageType.Log,
                        WebInspector.ConsoleMessage.MessageLevel.Warning,
                        -1,
                        this.url,
                        1,
                        String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toUIString(this.type), this.mimeType),
                        null,
                        null);
                break;
        }

        if (msg)
            WebInspector.console.addMessage(msg);
    },

    get content()
    {
        return this._content;
    },

    get contentTimestamp()
    {
        return this._contentTimestamp;
    },

    setInitialContent: function(content)
    {
        this._content = content;
    },

    isEditable: function()
    {
        if (this._actualResource)
            return false;
        var binding = WebInspector.Resource._domainModelBindings[this.type];
        return binding && binding.canSetContent(this);
    },

    setContent: function(newContent, majorChange, callback)
    {
        if (!this.isEditable(this)) {
            if (callback)
                callback("Resource is not editable");
            return;
        }
        var binding = WebInspector.Resource._domainModelBindings[this.type];
        binding.setContent(this, newContent, majorChange, callback);
    },

    addRevision: function(newContent)
    {
        var revision = new WebInspector.ResourceRevision(this, this._content, this._contentTimestamp);
        this.history.push(revision);

        this._content = newContent;
        this._contentTimestamp = new Date();

        this.dispatchEventToListeners(WebInspector.Resource.Events.RevisionAdded, revision);
    },

    requestContent: function(callback)
    {
        // We do not support content retrieval for WebSockets at the moment.
        // Since WebSockets are potentially long-living, fail requests immediately
        // to prevent caller blocking until resource is marked as finished.
        if (this.type === WebInspector.Resource.Type.WebSocket) {
            callback(null, null);
            return;
        }
        if (typeof this._content !== "undefined") {
            callback(this.content, this._contentEncoded);
            return;
        }
        this._pendingContentCallbacks.push(callback);
        if (this.finished)
            this._innerRequestContent();
    },

    populateImageSource: function(image)
    {
        function onResourceContent()
        {
            image.src = this._contentURL();
        }

        if (Preferences.useDataURLForResourceImageIcons)
            this.requestContent(onResourceContent.bind(this));
        else
            image.src = this.url;
    },

    isDataURL: function()
    {
        return this.url.match(/^data:/i);
    },
    
    _contentURL: function()
    {
        const maxDataUrlSize = 1024 * 1024;
        // If resource content is not available or won't fit a data URL, fall back to using original URL.
        if (this._content == null || this._content.length > maxDataUrlSize)
            return this.url;

        return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
    },

    _innerRequestContent: function()
    {
        if (this._contentRequested)
            return;
        this._contentRequested = true;
        this._contentEncoded = !WebInspector.Resource.Type.isTextType(this.type);

        function onResourceContent(data)
        {
            this._content = data;
            this._originalContent = data;
            var callbacks = this._pendingContentCallbacks.slice();
            for (var i = 0; i < callbacks.length; ++i)
                callbacks[i](this._content, this._contentEncoded);
            this._pendingContentCallbacks.length = 0;
            delete this._contentRequested;
        }
        WebInspector.networkManager.requestContent(this, this._contentEncoded, onResourceContent.bind(this));
    }
}

WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.ResourceRevision = function(resource, content, timestamp)
{
    this._resource = resource;
    this._content = content;
    this._timestamp = timestamp;
}

WebInspector.ResourceRevision.prototype = {
    get resource()
    {
        return this._resource;
    },

    get timestamp()
    {
        return this._timestamp;
    },

    get content()
    {
        return this._content;
    },

    revertToThis: function()
    {
        function revert(content)
        {
            this._resource.setContent(content, true);
        }
        this.requestContent(revert.bind(this));
    },

    requestContent: function(callback)
    {
        if (typeof this._content === "string") {
            callback(this._content);
            return;
        }

        // If we are here, this is initial revision. First, look up content fetched over the wire.
        if (typeof this.resource._originalContent === "string") {
            this._content = this._resource._originalContent;
            callback(this._content);
            return;
        }

        // If unsuccessful, request the content.
        function mycallback(content)
        {
            this._content = content;
            callback(content);
        }
        WebInspector.networkManager.requestContent(this._resource, false, mycallback.bind(this));
    }
}

WebInspector.ResourceDomainModelBinding = function()
{
}

WebInspector.ResourceDomainModelBinding.prototype = {
    canSetContent: function()
    {
        // Implemented by the domains.
        return true;
    },

    setContent: function(resource, content, majorChange, callback)
    {
        // Implemented by the domains.
    }
}
