/*
 * Copyright (C) 2013, 2014 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.JavaScriptBreakpoint = class JavaScriptBreakpoint extends WI.Breakpoint
{
    constructor(sourceCodeLocation, {contentIdentifier, resolved, disabled, condition, actions, ignoreCount, autoContinue} = {})
    {
        console.assert(sourceCodeLocation instanceof WI.SourceCodeLocation, sourceCodeLocation);
        console.assert(!contentIdentifier || typeof contentIdentifier === "string", contentIdentifier);
        console.assert(resolved === undefined || typeof resolved === "boolean", resolved);

        super({disabled, condition, actions, ignoreCount, autoContinue});

        this._id = null;
        this._sourceCodeLocation = sourceCodeLocation;

        let sourceCode = this._sourceCodeLocation.sourceCode;
        if (sourceCode) {
            this._contentIdentifier = sourceCode.contentIdentifier;
            console.assert(!contentIdentifier || contentIdentifier === this._contentIdentifier, "The content identifier from the source code should match the given value.");
        } else
            this._contentIdentifier = contentIdentifier || null;
        console.assert(this._contentIdentifier || this._isSpecial(), "There should always be a content identifier for a breakpoint.");

        this._scriptIdentifier = sourceCode instanceof WI.Script ? sourceCode.id : null;
        this._target = sourceCode instanceof WI.Script ? sourceCode.target : null;
        this._resolved = !!resolved;

        this._sourceCodeLocation.addEventListener(WI.SourceCodeLocation.Event.LocationChanged, this._sourceCodeLocationLocationChanged, this);
        this._sourceCodeLocation.addEventListener(WI.SourceCodeLocation.Event.DisplayLocationChanged, this._sourceCodeLocationDisplayLocationChanged, this);
    }

    // Static

    static supportsMicrotasks(parameter)
    {
        // COMPATIBILITY (iOS 13): Debugger.setPauseOnMicrotasks did not exist yet.
        return InspectorBackend.hasCommand("Debugger.setPauseOnMicrotasks", parameter);
    }

    static supportsDebuggerStatements(parameter)
    {
        // COMPATIBILITY (iOS 13.1): Debugger.setPauseOnDebuggerStatements did not exist yet.
        return InspectorBackend.hasCommand("Debugger.setPauseOnDebuggerStatements", parameter);
    }

    // Import / Export

    static fromJSON(json)
    {
        const sourceCode = null;
        return new WI.JavaScriptBreakpoint(new WI.SourceCodeLocation(sourceCode, json.lineNumber || 0, json.columnNumber || 0), {
            // The 'url' fallback is for transitioning from older frontends and should be removed.
            contentIdentifier: json.contentIdentifier || json.url,
            resolved: json.resolved,
            disabled: json.disabled,
            condition: json.condition,
            actions: json.actions?.map((actionJSON) => WI.BreakpointAction.fromJSON(actionJSON)) || [],
            ignoreCount: json.ignoreCount,
            autoContinue: json.autoContinue,
        });
    }

    toJSON(key)
    {
        // The id, scriptIdentifier, target, and resolved state are tied to the current session, so don't include them for serialization.
        let json = super.toJSON(key);
        if (this._contentIdentifier)
            json.contentIdentifier = this._contentIdentifier;
        if (isFinite(this._sourceCodeLocation.lineNumber))
            json.lineNumber = this._sourceCodeLocation.lineNumber;
        if (isFinite(this._sourceCodeLocation.columnNumber))
            json.columnNumber = this._sourceCodeLocation.columnNumber;
        if (key === WI.ObjectStore.toJSONSymbol)
            json[WI.objectStores.breakpoints.keyPath] = this._contentIdentifier + ":" + this._sourceCodeLocation.lineNumber + ":" + this._sourceCodeLocation.columnNumber;
        return json;
    }

    // Public

    get sourceCodeLocation() { return this._sourceCodeLocation; }
    get contentIdentifier() { return this._contentIdentifier; }
    get scriptIdentifier() { return this._scriptIdentifier; }
    get target() { return this._target; }

    get displayName()
    {
        switch (this) {
        case WI.debuggerManager.debuggerStatementsBreakpoint:
            return WI.repeatedUIString.debuggerStatements();

        case WI.debuggerManager.allExceptionsBreakpoint:
            return WI.repeatedUIString.allExceptions();

        case WI.debuggerManager.uncaughtExceptionsBreakpoint:
            return WI.repeatedUIString.uncaughtExceptions();

        case WI.debuggerManager.assertionFailuresBreakpoint:
            return WI.repeatedUIString.assertionFailures();

        case WI.debuggerManager.allMicrotasksBreakpoint:
            return WI.repeatedUIString.allMicrotasks();
        }

        return this._sourceCodeLocation.displayLocationString()
    }

    get special()
    {
        switch (this) {
        case WI.debuggerManager.debuggerStatementsBreakpoint:
        case WI.debuggerManager.allExceptionsBreakpoint:
        case WI.debuggerManager.uncaughtExceptionsBreakpoint:
        case WI.debuggerManager.assertionFailuresBreakpoint:
        case WI.debuggerManager.allMicrotasksBreakpoint:
            return true;
        }

        if (this._isSpecial())
            return true;

        return super.special;
    }

    get removable()
    {
        switch (this) {
        case WI.debuggerManager.debuggerStatementsBreakpoint:
        case WI.debuggerManager.allExceptionsBreakpoint:
        case WI.debuggerManager.uncaughtExceptionsBreakpoint:
            return false;
        }

        return super.removable;
    }

    get editable()
    {
        switch (this) {
        case WI.debuggerManager.debuggerStatementsBreakpoint:
            // COMPATIBILITY (iOS 14): Debugger.setPauseOnDebuggerStatements did not have an "options" parameter yet.
            return WI.JavaScriptBreakpoint.supportsDebuggerStatements("options");

        case WI.debuggerManager.allExceptionsBreakpoint:
        case WI.debuggerManager.uncaughtExceptionsBreakpoint:
            // COMPATIBILITY (iOS 14): Debugger.setPauseOnExceptions did not have an "options" parameter yet.
            return InspectorBackend.hasCommand("Debugger.setPauseOnExceptions", "options");

        case WI.debuggerManager.assertionFailuresBreakpoint:
            // COMPATIBILITY (iOS 14): Debugger.setPauseOnAssertions did not have an "options" parameter yet.
            return InspectorBackend.hasCommand("Debugger.setPauseOnAssertions", "options");

        case WI.debuggerManager.allMicrotasksBreakpoint:
            // COMPATIBILITY (iOS 14): Debugger.setPauseOnMicrotasks did not have an "options" parameter yet.
            return WI.JavaScriptBreakpoint.supportsMicrotasks("options");
        }

        return true;
    }

    get identifier()
    {
        return this._id;
    }

    set identifier(id)
    {
        this._id = id || null;
    }

    get resolved()
    {
        return super.resolved && this._resolved;
    }

    set resolved(resolved)
    {
        if (this._resolved === resolved)
            return;

        console.assert(!resolved || this._sourceCodeLocation.sourceCode || this._isSpecial(), "Breakpoints must have a SourceCode to be resolved.", this);

        this._resolved = resolved || false;

        this.dispatchEventToListeners(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange);
    }

    remove()
    {
        super.remove();

        WI.debuggerManager.removeBreakpoint(this);
    }

    saveIdentityToCookie(cookie)
    {
        cookie["javascript-breakpoint-content-identifier"] = this._contentIdentifier;
        cookie["javascript-breakpoint-line-number"] = this._sourceCodeLocation.lineNumber;
        cookie["javascript-breakpoint-column-number"] = this._sourceCodeLocation.columnNumber;
    }

    // Private

    _isSpecial()
    {
        return this._sourceCodeLocation.isEqual(WI.SourceCodeLocation.specialBreakpointLocation);
    }

    _sourceCodeLocationLocationChanged(event)
    {
        this.dispatchEventToListeners(WI.JavaScriptBreakpoint.Event.LocationDidChange, event.data);
    }

    _sourceCodeLocationDisplayLocationChanged(event)
    {
        this.dispatchEventToListeners(WI.JavaScriptBreakpoint.Event.DisplayLocationDidChange, event.data);
    }
};

WI.JavaScriptBreakpoint.TypeIdentifier = "javascript-breakpoint";

WI.JavaScriptBreakpoint.Event = {
    ResolvedStateDidChange: "javascript-breakpoint-resolved-state-did-change",
    LocationDidChange: "javascript-breakpoint-location-did-change",
    DisplayLocationDidChange: "javascript-breakpoint-display-location-did-change",
};

WI.JavaScriptBreakpoint.ReferencePage = WI.ReferencePage.JavaScriptBreakpoints;
