// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>}
 * @unrestricted
 */
export default class ExecutionContextSelector {
  /**
   * @param {!SDK.TargetManager} targetManager
   * @param {!UI.Context} context
   */
  constructor(targetManager, context) {
    context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this);
    context.addFlavorChangeListener(SDK.Target, this._targetChanged, this);

    targetManager.addModelListener(
        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
    targetManager.addModelListener(
        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
    targetManager.addModelListener(
        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextOrderChanged, this._onExecutionContextOrderChanged,
        this);
    this._targetManager = targetManager;
    this._context = context;
    targetManager.observeModels(SDK.RuntimeModel, this);
  }

  /**
   * @override
   * @param {!SDK.RuntimeModel} runtimeModel
   */
  modelAdded(runtimeModel) {
    // Defer selecting default target since we need all clients to get their
    // targetAdded notifications first.
    setImmediate(deferred.bind(this));

    /**
     * @this {Main.ExecutionContextSelector}
     */
    function deferred() {
      // We always want the second context for the service worker targets.
      if (!this._context.flavor(SDK.Target)) {
        this._context.setFlavor(SDK.Target, runtimeModel.target());
      }
    }
  }

  /**
   * @override
   * @param {!SDK.RuntimeModel} runtimeModel
   */
  modelRemoved(runtimeModel) {
    const currentExecutionContext = this._context.flavor(SDK.ExecutionContext);
    if (currentExecutionContext && currentExecutionContext.runtimeModel === runtimeModel) {
      this._currentExecutionContextGone();
    }

    const models = this._targetManager.models(SDK.RuntimeModel);
    if (this._context.flavor(SDK.Target) === runtimeModel.target() && models.length) {
      this._context.setFlavor(SDK.Target, models[0].target());
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _executionContextChanged(event) {
    const newContext = /** @type {?SDK.ExecutionContext} */ (event.data);
    if (newContext) {
      this._context.setFlavor(SDK.Target, newContext.target());
      if (!this._ignoreContextChanged) {
        this._lastSelectedContextId = this._contextPersistentId(newContext);
      }
    }
  }

  /**
   * @param {!SDK.ExecutionContext} executionContext
   * @return {string}
   */
  _contextPersistentId(executionContext) {
    return executionContext.isDefault ? executionContext.target().name() + ':' + executionContext.frameId : '';
  }

  /**
   * @param {!Common.Event} event
   */
  _targetChanged(event) {
    const newTarget = /** @type {?SDK.Target} */ (event.data);
    const currentContext = this._context.flavor(SDK.ExecutionContext);

    if (!newTarget || (currentContext && currentContext.target() === newTarget)) {
      return;
    }

    const runtimeModel = newTarget.model(SDK.RuntimeModel);
    const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
    if (!executionContexts.length) {
      return;
    }

    let newContext = null;
    for (let i = 0; i < executionContexts.length && !newContext; ++i) {
      if (this._shouldSwitchToContext(executionContexts[i])) {
        newContext = executionContexts[i];
      }
    }
    for (let i = 0; i < executionContexts.length && !newContext; ++i) {
      if (this._isDefaultContext(executionContexts[i])) {
        newContext = executionContexts[i];
      }
    }
    this._ignoreContextChanged = true;
    this._context.setFlavor(SDK.ExecutionContext, newContext || executionContexts[0]);
    this._ignoreContextChanged = false;
  }

  /**
   * @param {!SDK.ExecutionContext} executionContext
   * @return {boolean}
   */
  _shouldSwitchToContext(executionContext) {
    if (this._lastSelectedContextId && this._lastSelectedContextId === this._contextPersistentId(executionContext)) {
      return true;
    }
    if (!this._lastSelectedContextId && this._isDefaultContext(executionContext)) {
      return true;
    }
    return false;
  }

  /**
   * @param {!SDK.ExecutionContext} executionContext
   * @return {boolean}
   */
  _isDefaultContext(executionContext) {
    if (!executionContext.isDefault || !executionContext.frameId) {
      return false;
    }
    if (executionContext.target().parentTarget()) {
      return false;
    }
    const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel);
    const frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
    if (frame && frame.isTopFrame()) {
      return true;
    }
    return false;
  }

  /**
   * @param {!Common.Event} event
   */
  _onExecutionContextCreated(event) {
    this._switchContextIfNecessary(/** @type {!SDK.ExecutionContext} */ (event.data));
  }

  /**
   * @param {!Common.Event} event
   */
  _onExecutionContextDestroyed(event) {
    const executionContext = /** @type {!SDK.ExecutionContext}*/ (event.data);
    if (this._context.flavor(SDK.ExecutionContext) === executionContext) {
      this._currentExecutionContextGone();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _onExecutionContextOrderChanged(event) {
    const runtimeModel = /** @type {!SDK.RuntimeModel} */ (event.data);
    const executionContexts = runtimeModel.executionContexts();
    for (let i = 0; i < executionContexts.length; i++) {
      if (this._switchContextIfNecessary(executionContexts[i])) {
        break;
      }
    }
  }

  /**
   * @param {!SDK.ExecutionContext} executionContext
   * @return {boolean}
   */
  _switchContextIfNecessary(executionContext) {
    if (!this._context.flavor(SDK.ExecutionContext) || this._shouldSwitchToContext(executionContext)) {
      this._ignoreContextChanged = true;
      this._context.setFlavor(SDK.ExecutionContext, executionContext);
      this._ignoreContextChanged = false;
      return true;
    }
    return false;
  }

  _currentExecutionContextGone() {
    const runtimeModels = this._targetManager.models(SDK.RuntimeModel);
    let newContext = null;
    for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
      const executionContexts = runtimeModels[i].executionContexts();
      for (const executionContext of executionContexts) {
        if (this._isDefaultContext(executionContext)) {
          newContext = executionContext;
          break;
        }
      }
    }
    if (!newContext) {
      for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
        const executionContexts = runtimeModels[i].executionContexts();
        if (executionContexts.length) {
          newContext = executionContexts[0];
          break;
        }
      }
    }
    this._ignoreContextChanged = true;
    this._context.setFlavor(SDK.ExecutionContext, newContext);
    this._ignoreContextChanged = false;
  }
}

/* Legacy exported object */
self.Main = self.Main || {};

/* Legacy exported object */
Main = Main || {};

/**
 * @constructor
 */
Main.ExecutionContextSelector = ExecutionContextSelector;
