// 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}
 */

BindingsTestRunner.cleanupURL = function(url) {
  if (!url.startsWith('debugger://'))
    return url;

  return url.replace(/VM\d+/g, 'VM[XXX]');
};

BindingsTestRunner.dumpWorkspace = function(previousSnapshot) {
  const uiSourceCodes = Workspace.workspace.uiSourceCodes().slice();
  let urls = uiSourceCodes.map(code => code.url());

  urls = urls.map(BindingsTestRunner.cleanupURL);

  urls.sort(String.caseInsensetiveComparator);
  const isAdded = new Array(urls.length).fill(false);
  let removedLines = [];

  if (previousSnapshot) {
    const diff = Diff.Diff.lineDiff(previousSnapshot, urls);
    const removedEntries = diff.filter(entry => entry[0] === Diff.Diff.Operation.Delete).map(entry => entry[1]);
    removedLines = [].concat.apply([], removedEntries);
    let index = 0;

    for (const entry of diff) {
      if (entry[0] === Diff.Diff.Operation.Delete)
        continue;

      if (entry[0] === Diff.Diff.Operation.Equal) {
        index += entry[1].length;
        continue;
      }

      // eslint-disable-next-line no-unused-vars
      for (const line of entry[1])
        isAdded[index++] = true;
    }

    const addedEntries = diff.filter(entry => entry[0] === Diff.Diff.Operation.Insert).map(entry => entry[1]);
    addedLines = [].concat.apply([], addedEntries);
  }

  TestRunner.addResult(`Removed: ${removedLines.length} uiSourceCodes`);

  for (const url of removedLines)
    TestRunner.addResult('[-] ' + url);

  TestRunner.addResult(`Workspace: ${urls.length} uiSourceCodes.`);

  for (let i = 0; i < urls.length; ++i) {
    const url = urls[i];
    const prefix = (isAdded[i] ? '[+] ' : '    ');
    TestRunner.addResult(prefix + url);
  }

  return urls;
};

BindingsTestRunner.attachFrame = function(frameId, url, evalSourceURL) {
  let evalSource = `(${attachFrame.toString()})('${frameId}', '${url}')`;

  if (evalSourceURL)
    evalSource += '//# sourceURL=' + evalSourceURL;

  return TestRunner.evaluateInPageAsync(evalSource);

  function attachFrame(frameId, url) {
    const frame = document.createElement('iframe');
    frame.src = url;
    frame.id = frameId;
    document.body.appendChild(frame);
    return new Promise(x => frame.onload = x);
  }
};

BindingsTestRunner.detachFrame = function(frameId, evalSourceURL) {
  let evalSource = `(${detachFrame.toString()})('${frameId}')`;

  if (evalSourceURL)
    evalSource += '//# sourceURL=' + evalSourceURL;

  return TestRunner.evaluateInPageAnonymously(evalSource);

  function detachFrame(frameId) {
    const frame = document.getElementById(frameId);
    frame.remove();
  }
};

BindingsTestRunner.navigateFrame = function(frameId, navigateURL, evalSourceURL) {
  let evalSource = `(${navigateFrame.toString()})('${frameId}', '${navigateURL}')`;

  if (evalSourceURL)
    evalSource += '//# sourceURL=' + evalSourceURL;

  return TestRunner.evaluateInPageAsync(evalSource);

  function navigateFrame(frameId, url) {
    const frame = document.getElementById(frameId);
    frame.src = url;
    return new Promise(x => frame.onload = x);
  }
};

BindingsTestRunner.attachShadowDOM = function(id, templateSelector, evalSourceURL) {
  let evalSource = `(${createShadowDOM.toString()})('${id}', '${templateSelector}')`;

  if (evalSourceURL)
    evalSource += '//# sourceURL=' + evalSourceURL;

  return TestRunner.evaluateInPageAnonymously(evalSource);

  function createShadowDOM(id, templateSelector) {
    const shadowHost = document.createElement('div');
    shadowHost.setAttribute('id', id);

    const shadowRoot = shadowHost.attachShadow({mode: 'open'});

    const t = document.querySelector(templateSelector);
    const instance = t.content.cloneNode(true);
    shadowRoot.appendChild(instance);
    document.body.appendChild(shadowHost);
  }
};

BindingsTestRunner.detachShadowDOM = function(id, evalSourceURL) {
  let evalSource = `(${removeShadowDOM.toString()})('${id}')`;

  if (evalSourceURL)
    evalSource += '//# sourceURL=' + evalSourceURL;

  return TestRunner.evaluateInPageAnonymously(evalSource);

  function removeShadowDOM(id) {
    document.querySelector('#' + id).remove();
  }
};

BindingsTestRunner.waitForStyleSheetRemoved = function(urlSuffix) {
  let fulfill;
  const promise = new Promise(x => fulfill = x);
  TestRunner.cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, onStyleSheetRemoved);
  return promise;

  function onStyleSheetRemoved(event) {
    const styleSheetHeader = event.data;

    if (!styleSheetHeader.resourceURL().endsWith(urlSuffix))
      return;

    TestRunner.cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetRemoved, onStyleSheetRemoved);
    fulfill();
  }
};

TestRunner.addSniffer(Bindings.CompilerScriptMapping.prototype, '_sourceMapAttachedForTest', onSourceMap, true);
TestRunner.addSniffer(Bindings.SASSSourceMapping.prototype, '_sourceMapAttachedForTest', onSourceMap, true);
const sourceMapCallbacks = new Map();

function onSourceMap(sourceMap) {
  for (const urlSuffix of sourceMapCallbacks.keys()) {
    if (sourceMap.url().endsWith(urlSuffix)) {
      const callback = sourceMapCallbacks.get(urlSuffix);
      callback.call(null);
      sourceMapCallbacks.delete(urlSuffix);
    }
  }
}

BindingsTestRunner.waitForSourceMap = function(sourceMapURLSuffix) {
  let fulfill;
  const promise = new Promise(x => fulfill = x);
  sourceMapCallbacks.set(sourceMapURLSuffix, fulfill);
  return promise;
};

const locationPool = new Bindings.LiveLocationPool();
const nameSymbol = Symbol('LiveLocationNameForTest');
const createdSymbol = Symbol('LiveLocationCreated');

BindingsTestRunner.createDebuggerLiveLocation = function(name, urlSuffix, lineNumber, columnNumber) {
  const script = TestRunner.debuggerModel.scripts().find(script => script.sourceURL.endsWith(urlSuffix));
  const rawLocation = TestRunner.debuggerModel.createRawLocation(script, lineNumber || 0, columnNumber || 0);
  return Bindings.debuggerWorkspaceBinding.createLiveLocation(
      rawLocation, updateDelegate.bind(null, name), locationPool);
};

BindingsTestRunner.createCSSLiveLocation = function(name, urlSuffix, lineNumber, columnNumber) {
  const header = TestRunner.cssModel.styleSheetHeaders().find(header => header.resourceURL().endsWith(urlSuffix));
  const rawLocation = new SDK.CSSLocation(header, lineNumber || 0, columnNumber || 0);
  return Bindings.cssWorkspaceBinding.createLiveLocation(rawLocation, updateDelegate.bind(null, name), locationPool);
};

function updateDelegate(name, liveLocation) {
  liveLocation[nameSymbol] = name;
  const hint = (liveLocation[createdSymbol] ? '[ UPDATE ]' : '[ CREATE ]');
  liveLocation[createdSymbol] = true;
  BindingsTestRunner.dumpLocation(liveLocation, hint);
}

BindingsTestRunner.dumpLocation = function(liveLocation, hint) {
  hint = hint || '[  GET   ]';
  const prefix = `${hint}  LiveLocation-${liveLocation[nameSymbol]}: `;
  const uiLocation = liveLocation.uiLocation();

  if (!uiLocation) {
    TestRunner.addResult(prefix + 'null');
    return;
  }

  TestRunner.addResult(
      prefix + BindingsTestRunner.cleanupURL(uiLocation.uiSourceCode.url()) + ':' + uiLocation.lineNumber + ':' +
      uiLocation.columnNumber);
};
