// Copyright 2017 The Chromium Authors. All
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview using private properties isn't a Closure violation in tests.
 * @suppress {accessControls}
 */

let id = 0;

function nextId(prefix) {
  return (prefix || '') + ++id;
}

SDKTestRunner.connectToPage = function(targetName, pageMock, makeMainTarget) {
  const mockTarget = SDK.targetManager.createTarget(
      nextId('mock-target-'), targetName, pageMock.capabilities(), params => pageMock.createConnection(params));

  if (makeMainTarget) {
    SDK.targetManager._targets = SDK.targetManager._targets.filter(target => target !== mockTarget);
    SDK.targetManager._targets.unshift(mockTarget);
  }

  return mockTarget;
};

SDKTestRunner.PageMock = class {
  constructor(url) {
    this._url = url;
    this._capabilities = SDK.Target.Capability.DOM | SDK.Target.Capability.JS | SDK.Target.Capability.Browser;
    this._enabledDomains = new Set();

    this._mainFrame =
        {id: nextId(), loaderId: nextId(), mimeType: 'text/html', securityOrigin: this._url, url: this._url};

    this._executionContexts = [];
    this._executionContexts.push(this._createExecutionContext(this._mainFrame, false));
    this._scripts = [];
    this._scriptContents = new Map();

    this._dispatchMap = {
      'Debugger.enable': this._debuggerEnable,
      'Debugger.getScriptSource': this._debuggerGetScriptSource,
      'Debugger.setBlackboxPatterns': (id, params) => this._sendResponse(id, {}),
      'Runtime.enable': this._runtimeEnable,
      'Page.enable': this._pageEnable,
      'Page.getResourceTree': this._pageGetResourceTree
    };
  }

  capabilities() {
    return this._capabilities;
  }

  disableDOMCapability() {
    this._capabilities = this._capabilities & ~SDK.Target.Capability.DOM;
  }

  createConnection(params) {
    this._enabledDomains.clear();
    this._connection = new MockPageConnection(this, params);
    return this._connection;
  }

  evalScript(url, content, isContentScript) {
    const id = nextId();
    content += '\n//# sourceURL=' + url;
    this._scriptContents.set(id, content);
    let context = this._executionContexts.find(context => context.auxData.isDefault !== isContentScript);

    if (!context) {
      context = this._createExecutionContext(this._mainFrame, isContentScript);

      this._fireEvent('Runtime.executionContextCreated', {context: context});
    }

    const text = new TextUtils.Text(content);

    const script = {
      scriptId: id,
      url: url,
      startLine: 0,
      startColumn: 0,
      endLine: text.lineCount(),
      endColumn: text.lineAt(text.lineCount()).length - 1,
      executionContextId: context.id,
      hash: String.hashCode(content),
      executionContextAuxData: context.auxData,
      sourceMapURL: '',
      hasSourceURL: true,
      isLiveEdit: false,
      isModule: false,
      length: content.length
    };

    this._scripts.push(script);
    this._fireEvent('Debugger.scriptParsed', script);
  }

  reload() {
    this._fireEvent('Page.frameStartedLoading', {frameId: this._mainFrame.id});

    for (const context of this._executionContexts)
      this._fireEvent('Runtime.executionContextDestroyed', {executionContextId: context.id});


    this._scripts = [];
    this._scriptContents.clear();
    this._executionContexts = [];
    this._fireEvent('Runtime.executionContextsCleared', {});
    this._executionContexts.push(this._createExecutionContext(this._mainFrame, false));

    for (const context of this._executionContexts)
      this._fireEvent('Runtime.executionContextCreated', {context: context});


    this._fireEvent('Page.frameNavigated', {frame: this._mainFrame});

    this._fireEvent('Page.loadEventFired', {timestamp: Date.now() / 1000});

    this._fireEvent('Page.frameStoppedLoading', {frameId: this._mainFrame.id});

    this._fireEvent('Page.domContentEventFired', {timestamp: Date.now() / 1000});
  }

  close() {
    if (this._connection) {
      this._connection.disconnect();
      this._connection = null;
    }
  }

  _createExecutionContext(frame, isContentScript) {
    return {
      id: nextId(),

      auxData: {isDefault: !isContentScript, frameId: frame.id},

      origin: frame.securityOrigin,
      name: ''
    };
  }

  _debuggerEnable(id, params) {
    this._enabledDomains.add('Debugger');
    this._sendResponse(id, {});

    for (const script of this._scripts)
      this._fireEvent('Debugger.scriptParsed', script);
  }

  _debuggerGetScriptSource(id, params) {
    if (!this._scriptContents.has(params.scriptId)) {
      this._sendResponse(id, undefined, {message: 'Can\'t get script content for id ' + params.scriptId, code: 1});

      return;
    }

    const result = {scriptSource: this._scriptContents.get(params.scriptId)};

    this._sendResponse(id, result);
  }

  _runtimeEnable(id, params) {
    this._enabledDomains.add('Runtime');
    this._sendResponse(id, {});

    for (const context of this._executionContexts)
      this._fireEvent('Runtime.executionContextCreated', {context: context});
  }

  _pageEnable(id, params) {
    this._enabledDomains.add('Page');
    this._sendResponse(id, {});
  }

  _pageGetResourceTree(id, params) {
    const result = {frameTree: {frame: this._mainFrame, resources: []}};

    this._sendResponse(id, result);
  }

  _isSupportedDomain(methodName) {
    const domain = methodName.split('.')[0];

    if (domain === 'Page')
      return !!(this._capabilities & SDK.Target.Capability.DOM);

    return true;
  }

  _dispatch(id, methodName, params, message) {
    const handler = (this._isSupportedDomain(methodName) ? this._dispatchMap[methodName] : null);

    if (handler)
      return handler.call(this, id, params);

    this._sendResponse(
        id, undefined,
        {message: 'Can\'t handle command ' + methodName, code: Protocol.InspectorBackend.DevToolsStubErrorCode});
  }

  _sendResponse(id, result, error) {
    const message = {id: id, result: result, error: error};

    this._connection.sendMessageToDevTools(message);
  }

  _fireEvent(methodName, params) {
    const domain = methodName.split('.')[0];

    if (!this._enabledDomains.has(domain))
      return;

    const message = {method: methodName, params: params};

    this._connection.sendMessageToDevTools(message);
  }
};

MockPageConnection = class {
  constructor(page, params) {
    this._page = page;
    this._onMessage = params.onMessage;
    this._onDisconnect = params.onDisconnect;
  }

  sendMessageToDevTools(message) {
    setTimeout(() => this._onMessage.call(null, JSON.stringify(message)), 0);
  }

  sendMessage(message) {
    const json = JSON.parse(message);
    this._page._dispatch(json.id, json.method, json.params, message);
  }

  disconnect() {
    this._onDisconnect.call(null, 'force disconnect');
    this._onDisconnect = null;
    this._onMessage = null;
    return Promise.resolve();
  }
};
