/*
 * 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.mimeType;
    }

    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;
