/*
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.Script = class Script extends WI.SourceCode
{
    constructor(target, id, range, url, sourceType, injected, sourceURL, sourceMapURL)
    {
        super();

        console.assert(target instanceof WI.Target);
        console.assert(range instanceof WI.TextRange);

        this._target = target;
        this._id = id || null;
        this._range = range || null;
        this._url = url || null;
        this._sourceType = sourceType || WI.Script.SourceType.Program;
        this._sourceURL = sourceURL || null;
        this._sourceMappingURL = sourceMapURL || null;
        this._injected = injected || false;
        this._dynamicallyAddedScriptElement = false;
        this._scriptSyntaxTree = null;

        this._resource = this._resolveResource();

        // If this Script was a dynamically added <script> to a Document,
        // do not associate with the Document resource, instead associate
        // with the frame as a dynamic script.
        if (this._resource && this._resource.type === WI.Resource.Type.Document && !this._range.startLine && !this._range.startColumn) {
            console.assert(this._resource.isMainResource());
            let documentResource = this._resource;
            this._resource = null;
            this._dynamicallyAddedScriptElement = true;
            documentResource.parentFrame.addExtraScript(this);
            this._dynamicallyAddedScriptElementNumber = documentResource.parentFrame.extraScriptCollection.size;
        } else if (this._resource)
            this._resource.associateWithScript(this);

        if (isWebInspectorConsoleEvaluationScript(this._sourceURL)) {
            // Assign a unique number to the script object so it will stay the same.
            this._uniqueDisplayNameNumber = this.constructor._nextUniqueConsoleDisplayNameNumber++;
        }

        if (this._sourceMappingURL)
            WI.networkManager.downloadSourceMap(this._sourceMappingURL, this._url, this);
    }

    // Static

    static resetUniqueDisplayNameNumbers()
    {
        WI.Script._nextUniqueDisplayNameNumber = 1;
        WI.Script._nextUniqueConsoleDisplayNameNumber = 1;
    }

    // Public

    get target() { return this._target; }
    get id() { return this._id; }
    get range() { return this._range; }
    get url() { return this._url; }
    get sourceType() { return this._sourceType; }
    get sourceURL() { return this._sourceURL; }
    get sourceMappingURL() { return this._sourceMappingURL; }
    get injected() { return this._injected; }

    get contentIdentifier()
    {
        if (this._url)
            return this._url;

        if (!this._sourceURL)
            return null;

        // Since reused content identifiers can cause breakpoints
        // to show up in completely unrelated files, sourceURLs should
        // be unique where possible. The checks below exclude cases
        // where sourceURLs are intentionally reused and we would never
        // expect a breakpoint to be persisted across sessions.
        if (isWebInspectorConsoleEvaluationScript(this._sourceURL))
            return null;

        if (isWebInspectorInternalScript(this._sourceURL))
            return null;

        return this._sourceURL;
    }

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

    get mimeType()
    {
        return this._resource ? this._resource.mimeType : "text/javascript";
    }

    get isScript()
    {
        return true;
    }

    get displayName()
    {
        if (this._url && !this._dynamicallyAddedScriptElement)
            return WI.displayNameForURL(this._url, this.urlComponents);

        if (isWebInspectorConsoleEvaluationScript(this._sourceURL)) {
            console.assert(this._uniqueDisplayNameNumber);
            return WI.UIString("Console Evaluation %d").format(this._uniqueDisplayNameNumber);
        }

        if (this._sourceURL) {
            if (!this._sourceURLComponents)
                this._sourceURLComponents = parseURL(this._sourceURL);
            return WI.displayNameForURL(this._sourceURL, this._sourceURLComponents);
        }

        if (this._dynamicallyAddedScriptElement)
            return WI.UIString("Script Element %d").format(this._dynamicallyAddedScriptElementNumber);

        // Assign a unique number to the script object so it will stay the same.
        if (!this._uniqueDisplayNameNumber)
            this._uniqueDisplayNameNumber = this.constructor._nextUniqueDisplayNameNumber++;

        return WI.UIString("Anonymous Script %d").format(this._uniqueDisplayNameNumber);
    }

    get displayURL()
    {
        const isMultiLine = true;
        const dataURIMaxSize = 64;

        if (this._url)
            return WI.truncateURL(this._url, isMultiLine, dataURIMaxSize);
        if (this._sourceURL)
            return WI.truncateURL(this._sourceURL, isMultiLine, dataURIMaxSize);
        return null;
    }

    get dynamicallyAddedScriptElement()
    {
        return this._dynamicallyAddedScriptElement;
    }

    get anonymous()
    {
        return !this._resource && !this._url && !this._sourceURL;
    }

    get resource()
    {
        return this._resource;
    }

    get scriptSyntaxTree()
    {
        return this._scriptSyntaxTree;
    }

    isMainResource()
    {
        return this._target.mainResource === this;
    }

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

        if (!this._id) {
            // There is no identifier to request content with. Return false to cause the
            // pending callbacks to get null content.
            return Promise.reject(new Error("There is no identifier to request content with."));
        }

        return this._target.DebuggerAgent.getScriptSource(this._id);
    }

    saveIdentityToCookie(cookie)
    {
        cookie[WI.Script.URLCookieKey] = this.url;
        cookie[WI.Script.DisplayNameCookieKey] = this.displayName;
    }

    requestScriptSyntaxTree(callback)
    {
        if (this._scriptSyntaxTree) {
            setTimeout(() => { callback(this._scriptSyntaxTree); }, 0);
            return;
        }

        var makeSyntaxTreeAndCallCallback = (content) => {
            this._makeSyntaxTree(content);
            callback(this._scriptSyntaxTree);
        };

        var content = this.content;
        if (!content && this._resource && this._resource.type === WI.Resource.Type.Script && this._resource.finished)
            content = this._resource.content;
        if (content) {
            setTimeout(makeSyntaxTreeAndCallCallback, 0, content);
            return;
        }

        this.requestContent().then(function(parameters) {
            makeSyntaxTreeAndCallCallback(parameters.sourceCode.content);
        }).catch(function(error) {
            makeSyntaxTreeAndCallCallback(null);
        });
    }

    // Private

    _resolveResource()
    {
        // FIXME: We should be able to associate a Script with a Resource through identifiers,
        // we shouldn't need to lookup by URL, which is not safe with frames, where there might
        // be multiple resources with the same URL.
        // <rdar://problem/13373951> Scripts should be able to associate directly with a Resource

        // No URL, no resource.
        if (!this._url)
            return null;

        let resolver = WI.networkManager;
        if (this._target !== WI.mainTarget)
            resolver = this._target.resourceCollection;

        try {
            // Try with the Script's full URL.
            let resource = resolver.resourceForURL(this._url);
            if (resource)
                return resource;

            // Try with the Script's full decoded URL.
            let decodedURL = decodeURI(this._url);
            if (decodedURL !== this._url) {
                resource = resolver.resourceForURL(decodedURL);
                if (resource)
                    return resource;
            }

            // Next try removing any fragment in the original URL.
            let urlWithoutFragment = removeURLFragment(this._url);
            if (urlWithoutFragment !== this._url) {
                resource = resolver.resourceForURL(urlWithoutFragment);
                if (resource)
                    return resource;
            }

            // Finally try removing any fragment in the decoded URL.
            let decodedURLWithoutFragment = removeURLFragment(decodedURL);
            if (decodedURLWithoutFragment !== decodedURL) {
                resource = resolver.resourceForURL(decodedURLWithoutFragment);
                if (resource)
                    return resource;
            }
        } catch { }

        if (!this.isMainResource()) {
            for (let frame of WI.networkManager.frames) {
                if (frame.mainResource.type === WI.Resource.Type.Document && frame.mainResource.url.startsWith(this._url))
                    return frame.mainResource;
            }
        }

        return null;
    }

    _makeSyntaxTree(sourceText)
    {
        if (this._scriptSyntaxTree || !sourceText)
            return;

        this._scriptSyntaxTree = new WI.ScriptSyntaxTree(sourceText, this);
    }
};

WI.Script.SourceType = {
    Program: "script-source-type-program",
    Module: "script-source-type-module",
};

WI.Script.TypeIdentifier = "script";
WI.Script.URLCookieKey = "script-url";
WI.Script.DisplayNameCookieKey = "script-display-name";

WI.Script._nextUniqueDisplayNameNumber = 1;
WI.Script._nextUniqueConsoleDisplayNameNumber = 1;
