/*
 * Copyright (C) 2016-2018 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.TargetManager = class TargetManager extends WI.Object
{
    constructor()
    {
        super();

        this._targets = new Map;
        this._cachedTargetsList = null;
        this._seenPageTarget = false;
        this._transitionTimeoutIdentifier = undefined;
    }

    // Target

    initializeTarget(target)
    {
        // COMPATIBILITY (iOS 13): Target.setPauseOnStart did not exist yet.
        if (target.hasCommand("Target.setPauseOnStart"))
            target.TargetAgent.setPauseOnStart(true);
    }

    // Public

    get targets()
    {
        if (!this._cachedTargetsList)
            this._cachedTargetsList = Array.from(this._targets.values()).filter((target) => !(target instanceof WI.MultiplexingBackendTarget));
        return this._cachedTargetsList;
    }

    get workerTargets()
    {
        return this.targets.filter((target) => target.type === WI.TargetType.Worker);
    }

    get allTargets()
    {
        return Array.from(this._targets.values());
    }

    targetForIdentifier(targetId)
    {
        if (!targetId)
            return null;

        for (let target of this._targets.values()) {
            if (target.identifier === targetId)
                return target;
        }

        return null;
    }

    addTarget(target)
    {
        console.assert(target);
        console.assert(!this._targets.has(target.identifier));

        this._cachedTargetsList = null;
        this._targets.set(target.identifier, target);

        this.dispatchEventToListeners(WI.TargetManager.Event.TargetAdded, {target});
    }

    removeTarget(target)
    {
        console.assert(target);
        console.assert(target !== WI.mainTarget);

        this._cachedTargetsList = null;
        this._targets.delete(target.identifier);
        target.destroy();

        this.dispatchEventToListeners(WI.TargetManager.Event.TargetRemoved, {target});
    }

    createMultiplexingBackendTarget()
    {
        console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.WebPage);

        let target = new WI.MultiplexingBackendTarget;
        target.initialize();

        this._initializeBackendTarget(target);

        // Add the target without dispatching an event.
        this._targets.set(target.identifier, target);
    }

    createDirectBackendTarget()
    {
        console.assert(WI.sharedApp.debuggableType !== WI.DebuggableType.WebPage);

        let target = new WI.DirectBackendTarget;
        target.initialize();

        this._initializeBackendTarget(target);

        if (WI.sharedApp.debuggableType === WI.DebuggableType.Page)
            this._initializePageTarget(target);

        this.addTarget(target);
    }

    // TargetObserver

    targetCreated(parentTarget, targetInfo)
    {
        let connection = new InspectorBackend.TargetConnection(parentTarget, targetInfo.targetId);
        let subTarget = this._createTarget(parentTarget, targetInfo, connection);
        this._checkAndHandlePageTargetTransition(subTarget);
        subTarget.initialize();
        this.addTarget(subTarget);
    }

    didCommitProvisionalTarget(parentTarget, previousTargetId, newTargetId)
    {
        this.targetDestroyed(previousTargetId);
        let target = this._targets.get(newTargetId);
        console.assert(target);
        if (!target)
            return;

        target.didCommitProvisionalTarget();
        this._checkAndHandlePageTargetTransition(target);
        target.connection.dispatchProvisionalMessages();

        this.dispatchEventToListeners(WI.TargetManager.Event.DidCommitProvisionalTarget, {previousTargetId, target});
    }

    targetDestroyed(targetId)
    {
        let target = this._targets.get(targetId);
        if (!target)
            return;

        this._checkAndHandlePageTargetTermination(target);
        this.removeTarget(target);
    }

    dispatchMessageFromTarget(targetId, message)
    {
        let target = this._targets.get(targetId);
        console.assert(target);
        if (!target)
            return;

        if (target.isProvisional)
            target.connection.addProvisionalMessage(message);
        else
            target.connection.dispatch(message);
    }

    // Private

    _createTarget(parentTarget, targetInfo, connection)
    {
        // COMPATIBILITY (iOS 13.0): `Target.TargetInfo.isProvisional` and `Target.TargetInfo.isPaused` did not exist yet.
        let {targetId, type, isProvisional, isPaused} = targetInfo;

        switch (type) {
        case InspectorBackend.Enum.Target.TargetInfoType.Page:
            return new WI.PageTarget(parentTarget, targetId, WI.UIString("Page"), connection, {isProvisional, isPaused});
        case InspectorBackend.Enum.Target.TargetInfoType.Worker:
            return new WI.WorkerTarget(parentTarget, targetId, WI.UIString("Worker"), connection, {isPaused});
        case "serviceworker": // COMPATIBILITY (iOS 13): "serviceworker" was renamed to "service-worker".
        case InspectorBackend.Enum.Target.TargetInfoType.ServiceWorker:
            return new WI.WorkerTarget(parentTarget, targetId, WI.UIString("ServiceWorker"), connection, {isPaused});
        }

        throw "Unknown Target type: " + type;
    }

    _checkAndHandlePageTargetTransition(target)
    {
        if (target.type !== WI.TargetType.Page)
            return;

        if (target.isProvisional)
            return;

        // First page target.
        if (!WI.pageTarget && !this._seenPageTarget) {
            this._seenPageTarget = true;
            this._initializePageTarget(target);
            return;
        }

        // Transitioning page target.
        this._transitionPageTarget(target);
    }

    _checkAndHandlePageTargetTermination(target)
    {
        if (target.type !== WI.TargetType.Page)
            return;

        if (target.isProvisional)
            return;

        console.assert(target === WI.pageTarget);
        console.assert(this._seenPageTarget);

        // Terminating the page target.
        this._terminatePageTarget(target);

        // Ensure we transition in a reasonable amount of time, otherwise close.
        const timeToTransition = 2000;
        clearTimeout(this._transitionTimeoutIdentifier);
        this._transitionTimeoutIdentifier = setTimeout(() => {
            this._transitionTimeoutIdentifier = undefined;
            if (WI.pageTarget)
                return;
            if (WI.isEngineeringBuild)
                throw new Error("Error: No new pageTarget some time after last page target was terminated. Failed transition?");
            WI.close();
        }, timeToTransition);
    }

    _initializeBackendTarget(target)
    {
        console.assert(!WI.mainTarget);

        WI.backendTarget = target;

        this._resetMainExecutionContext();

        WI._backendTargetAvailablePromise.resolve();
    }

    _initializePageTarget(target)
    {
        console.assert(WI.sharedApp.isWebDebuggable());
        console.assert(target.type === WI.TargetType.Page || target instanceof WI.DirectBackendTarget);

        WI.pageTarget = target;

        this._resetMainExecutionContext();

        WI._pageTargetAvailablePromise.resolve();
    }

    _transitionPageTarget(target)
    {
        console.assert(!WI.pageTarget);
        console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.WebPage);
        console.assert(target.type === WI.TargetType.Page);

        WI.pageTarget = target;

        this._resetMainExecutionContext();

        // Actions to transition the page target.
        WI.notifications.dispatchEventToListeners(WI.Notification.TransitionPageTarget);
        WI.domManager.transitionPageTarget();
        WI.networkManager.transitionPageTarget();
        WI.timelineManager.transitionPageTarget();
    }

    _terminatePageTarget(target)
    {
        console.assert(WI.pageTarget);
        console.assert(WI.pageTarget === target);
        console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.WebPage);

        // Remove any Worker targets associated with this page.
        for (let workerTarget of this.workerTargets)
            WI.workerManager.workerTerminated(workerTarget.identifier);

        WI.pageTarget = null;
    }

    _resetMainExecutionContext()
    {
        if (WI.mainTarget instanceof WI.MultiplexingBackendTarget)
            return;

        if (WI.mainTarget.executionContext)
            WI.runtimeManager.activeExecutionContext = WI.mainTarget.executionContext;
    }
};

WI.TargetManager.Event = {
    TargetAdded: Symbol("target-manager-target-added"),
    TargetRemoved: Symbol("target-manager-target-removed"),
    DidCommitProvisionalTarget: "target-manager-provisional-target-committed",
};
