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

SourcesTestRunner.dumpSearchResults = function(searchResults) {
  function comparator(a, b) {
    a.url.localeCompare(b.url);
  }

  searchResults.sort(comparator);
  TestRunner.addResult('Search results: ');

  for (let i = 0; i < searchResults.length; i++) {
    TestRunner.addResult(
        'url: ' + searchResults[i].url.replace(/VM\d+/, 'VMXX') + ', matchesCount: ' + searchResults[i].matchesCount);
  }

  TestRunner.addResult('');
};

SourcesTestRunner.dumpSearchMatches = function(searchMatches) {
  TestRunner.addResult('Search matches: ');

  for (let i = 0; i < searchMatches.length; i++) {
    TestRunner.addResult(
        'lineNumber: ' + searchMatches[i].lineNumber + ', line: \'' + searchMatches[i].lineContent + '\'');
  }

  TestRunner.addResult('');
};

SourcesTestRunner.runSearchAndDumpResults = function(scope, searchConfig, callback) {
  const searchResults = [];
  const progress = new Common.Progress();
  scope.performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback);

  function searchResultCallback(searchResult) {
    searchResults.push(searchResult);
  }

  function searchFinishedCallback() {
    function comparator(searchResultA, searchResultB) {
      return searchResultA._uiSourceCode.url().compareTo(searchResultB._uiSourceCode.url());
    }

    searchResults.sort(comparator);

    for (let i = 0; i < searchResults.length; ++i) {
      const searchResult = searchResults[i];
      const uiSourceCode = searchResult._uiSourceCode;
      const searchMatches = searchResult._searchMatches;

      if (!searchMatches.length)
        continue;

      TestRunner.addResult(
          'Search result #' + (i + 1) + ': uiSourceCode.url = ' + uiSourceCode.url().replace(/VM\d+/, 'VMXX'));

      for (let j = 0; j < searchMatches.length; ++j) {
        const lineNumber = searchMatches[j].lineNumber;
        const lineContent = searchMatches[j].lineContent;
        TestRunner.addResult(
            '  search match #' + (j + 1) + ': lineNumber = ' + lineNumber + ', lineContent = \'' + lineContent + '\'');
      }
    }

    callback();
  }
};

SourcesTestRunner.replaceAndDumpChange = function(sourceFrame, searchConfig, replacement, replaceAll) {
  const modifiers = [];

  if (searchConfig.isRegex)
    modifiers.push('regex');

  if (searchConfig.caseSensitive)
    modifiers.push('caseSensitive');

  if (replaceAll)
    modifiers.push('replaceAll');

  const modifiersString = (modifiers.length ? ' (' + modifiers.join(', ') + ')' : '');
  TestRunner.addResult(
      'Running replace test for /' + searchConfig.query + '/' + replacement + '/ ' + modifiersString + ':');
  editor = sourceFrame._textEditor;
  const oldLines = [];

  for (let i = 0; i < editor.linesCount; ++i)
    oldLines.push(editor.line(i));

  const searchableView = UI.panels.sources.sourcesView().searchableView();
  searchableView.showSearchField();
  searchableView._caseSensitiveButton.setToggled(searchConfig.caseSensitive);
  searchableView._regexButton.setToggled(searchConfig.isRegex);
  searchableView._searchInputElement.value = searchConfig.query;
  searchableView._replaceToggleButton.setToggled(true);
  searchableView._updateSecondRowVisibility();
  searchableView._replaceInputElement.value = replacement;
  searchableView._performSearch(true, true);

  if (replaceAll)
    searchableView._replaceAll();
  else
    searchableView._replace();

  const newLines = [];

  for (let i = 0; i < editor.linesCount; ++i)
    newLines.push(editor.line(i));

  for (let i = 0; i < newLines.length; ++i) {
    if (oldLines[i] === newLines[i])
      continue;

    const oldLine = oldLines[i];
    const newLine = newLines[i];
    let prefixLength = 0;

    for (let j = 0; j < oldLine.length && j < newLine.length && newLine[j] === oldLine[j]; ++j)
      ++prefixLength;

    let postfixLength = 0;

    for (let j = 0; j < oldLine.length && j < newLine.length &&
         newLine[newLine.length - j - 1] === oldLine[oldLine.length - j - 1];
         ++j)
      ++postfixLength;

    const prefix = oldLine.substring(0, prefixLength);
    const removed = oldLine.substring(prefixLength, oldLine.length - postfixLength);
    const added = newLine.substring(prefixLength, newLine.length - postfixLength);
    const postfix = oldLine.substring(oldLine.length - postfixLength);
    TestRunner.addResult('  - ' + prefix + '#' + removed + '#' + added + '#' + postfix);
  }
};

TestRunner.deprecatedInitAsync(`
  if (window.GCController)
    GCController.collect();
`);
