// Copyright 2017 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.

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

/**
 * @param {!Sources.NavigatorView} navigatorView
 * @param {boolean=} dumpIcons
 */
SourcesTestRunner.dumpNavigatorView = function(navigatorView, dumpIcons) {
  dumpNavigatorTreeOutline(navigatorView._scriptsTree);

  /**
   * @param {string} prefix
   * @param {!UI.TreeElement} treeElement
   */
  function dumpNavigatorTreeElement(prefix, treeElement) {
    let titleText = '';
    if (treeElement._leadingIconsElement && dumpIcons) {
      let icons = treeElement._leadingIconsElement.querySelectorAll('[is=ui-icon]');
      icons = Array.prototype.slice.call(icons);
      const iconTypes = icons.map(icon => icon._iconType);
      if (iconTypes.length)
        titleText = titleText + '[' + iconTypes.join(', ') + '] ';
    }
    titleText += treeElement.title;
    if (treeElement._nodeType === Sources.NavigatorView.Types.FileSystem ||
        treeElement._nodeType === Sources.NavigatorView.Types.FileSystemFolder) {
      const hasMappedFiles = treeElement.listItemElement.classList.contains('has-mapped-files');
      if (!hasMappedFiles)
        titleText += ' [dimmed]';
    }
    TestRunner.addResult(prefix + titleText);
    treeElement.expand();
    const children = treeElement.children();
    for (let i = 0; i < children.length; ++i)
      dumpNavigatorTreeElement(prefix + '  ', children[i]);
  }

  /**
   * @param {!UI.TreeOutline} treeOutline
   */
  function dumpNavigatorTreeOutline(treeOutline) {
    const children = treeOutline.rootElement().children();
    for (let i = 0; i < children.length; ++i)
      dumpNavigatorTreeElement('', children[i]);
  }
};

/**
 * @param {!Sources.NavigatorView} view
 */
SourcesTestRunner.dumpNavigatorViewInAllModes = function(view) {
  ['frame', 'frame/domain', 'frame/domain/folder', 'domain', 'domain/folder'].forEach(
      SourcesTestRunner.dumpNavigatorViewInMode.bind(TestRunner, view));
};

/**
 * @param {!Sources.NavigatorView} view
 * @param {string} mode
 */
SourcesTestRunner.dumpNavigatorViewInMode = function(view, mode) {
  TestRunner.addResult(view instanceof Sources.NetworkNavigatorView ? 'Sources:' : 'Content Scripts:');
  view._groupByFrame = mode.includes('frame');
  view._groupByDomain = mode.includes('domain');
  view._groupByFolder = mode.includes('folder');
  view._resetForTest();
  TestRunner.addResult('-------- Setting mode: [' + mode + ']');
  SourcesTestRunner.dumpNavigatorView(view);
};

/**
 * @param {string} url
 * @param {string} content
 * @param {boolean=} isContentScript
 * @param {number=} worldId
 * @return {!Promise}
 */
SourcesTestRunner.addScriptUISourceCode = function(url, content, isContentScript, worldId) {
  content += '\n//# sourceURL=' + url;
  if (isContentScript)
    content = `testRunner.evaluateScriptInIsolatedWorld(${worldId}, \`${content}\`)`;
  TestRunner.evaluateInPageAnonymously(content);
  return TestRunner.waitForUISourceCode(url);
};

function testSourceMapping(text1, text2, mapping, testToken) {
  const originalPosition = text1.indexOf(testToken);
  TestRunner.assertTrue(originalPosition !== -1);
  const originalLocation = Formatter.Formatter.positionToLocation(text1.computeLineEndings(), originalPosition);
  const formattedLocation = mapping.originalToFormatted(originalLocation[0], originalLocation[1]);
  const formattedPosition =
      Formatter.Formatter.locationToPosition(text2.computeLineEndings(), formattedLocation[0], formattedLocation[1]);
  const expectedFormattedPosition = text2.indexOf(testToken);

  if (expectedFormattedPosition === formattedPosition)
    TestRunner.addResult(String.sprintf('Correct mapping for <%s>', testToken));
  else
    TestRunner.addResult(String.sprintf('ERROR: Wrong mapping for <%s>', testToken));
}

SourcesTestRunner.testPrettyPrint = function(mimeType, text, mappingQueries, next) {
  new Formatter.ScriptFormatter(mimeType, text, didFormatContent);

  function didFormatContent(formattedSource, mapping) {
    TestRunner.addResult('====== 8< ------');
    TestRunner.addResult(formattedSource);
    TestRunner.addResult('------ >8 ======');

    while (mappingQueries && mappingQueries.length)
      testSourceMapping(text, formattedSource, mapping, mappingQueries.shift());

    next();
  }
};

SourcesTestRunner.testJavascriptOutline = function(text) {
  let fulfill;
  const promise = new Promise(x => fulfill = x);
  Formatter.formatterWorkerPool().javaScriptOutline(text, onChunk);
  const items = [];
  return promise;

  function onChunk(isLastChunk, outlineItems) {
    items.pushAll(outlineItems);

    if (!isLastChunk)
      return;

    TestRunner.addResult('Text:');
    TestRunner.addResult(text.split('\n').map(line => '    ' + line).join('\n'));
    TestRunner.addResult('Outline:');

    for (const item of items)
      TestRunner.addResult('    ' + item.name + (item.arguments || '') + ':' + item.line + ':' + item.column);

    fulfill();
  }
};

SourcesTestRunner.dumpSwatchPositions = function(sourceFrame, bookmarkType) {
  const textEditor = sourceFrame.textEditor;
  const markers = textEditor.bookmarks(textEditor.fullRange(), bookmarkType);

  for (let i = 0; i < markers.length; i++) {
    const position = markers[i].position();
    const text = markers[i]._marker.widgetNode.firstChild.textContent;
    TestRunner.addResult('Line ' + position.startLine + ', Column ' + position.startColumn + ': ' + text);
  }
};
