// 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 {Workspace.ProjectSearchConfig}
 */
export class SearchConfig {
  /**
   * @param {string} query
   * @param {boolean} ignoreCase
   * @param {boolean} isRegex
   */
  constructor(query, ignoreCase, isRegex) {
    this._query = query;
    this._ignoreCase = ignoreCase;
    this._isRegex = isRegex;
    this._parse();
  }

  /**
   * @param {{query: string, ignoreCase: boolean, isRegex: boolean}} object
   * @return {!Search.SearchConfig}
   */
  static fromPlainObject(object) {
    return new SearchConfig(object.query, object.ignoreCase, object.isRegex);
  }

  /**
   * @override
   * @return {string}
   */
  query() {
    return this._query;
  }

  /**
   * @override
   * @return {boolean}
   */
  ignoreCase() {
    return this._ignoreCase;
  }

  /**
   * @override
   * @return {boolean}
   */
  isRegex() {
    return this._isRegex;
  }

  /**
   * @return {{query: string, ignoreCase: boolean, isRegex: boolean}}
   */
  toPlainObject() {
    return {query: this.query(), ignoreCase: this.ignoreCase(), isRegex: this.isRegex()};
  }

  _parse() {
    // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
    const quotedPattern = /"([^\\"]|\\.)+"/;
    // A word is a sequence of any symbols except space and backslash or any symbols escaped with a backslash, that does not start with file:.
    const unquotedWordPattern = /(\s*(?!-?f(ile)?:)[^\\ ]|\\.)+/;
    const unquotedPattern = unquotedWordPattern.source + '(\\s+' + unquotedWordPattern.source + ')*';


    const pattern = [
      '(\\s*' + FilePatternRegex.source + '\\s*)',
      '(' + quotedPattern.source + ')',
      '(' + unquotedPattern + ')',
    ].join('|');
    const regexp = new RegExp(pattern, 'g');
    const queryParts = this._query.match(regexp) || [];
    /**
     * @type {!Array.<!Search.SearchConfig.QueryTerm>}
     */
    this._fileQueries = [];

    /**
     * @type {!Array.<string>}
     */
    this._queries = [];

    for (let i = 0; i < queryParts.length; ++i) {
      const queryPart = queryParts[i];
      if (!queryPart) {
        continue;
      }
      const fileQuery = this._parseFileQuery(queryPart);
      if (fileQuery) {
        this._fileQueries.push(fileQuery);
        /** @type {!Array.<!Search.SearchConfig.RegexQuery>} */
        this._fileRegexQueries = this._fileRegexQueries || [];
        this._fileRegexQueries.push(
            {regex: new RegExp(fileQuery.text, this.ignoreCase ? 'i' : ''), isNegative: fileQuery.isNegative});
        continue;
      }
      if (this._isRegex) {
        this._queries.push(queryPart);
        continue;
      }
      if (queryPart.startsWith('"')) {
        if (!queryPart.endsWith('"')) {
          continue;
        }
        this._queries.push(this._parseQuotedQuery(queryPart));
        continue;
      }
      this._queries.push(this._parseUnquotedQuery(queryPart));
    }
  }

  /**
   * @override
   * @param {string} filePath
   * @return {boolean}
   */
  filePathMatchesFileQuery(filePath) {
    if (!this._fileRegexQueries) {
      return true;
    }
    for (let i = 0; i < this._fileRegexQueries.length; ++i) {
      if (!!filePath.match(this._fileRegexQueries[i].regex) === this._fileRegexQueries[i].isNegative) {
        return false;
      }
    }
    return true;
  }

  /**
   * @override
   * @return {!Array.<string>}
   */
  queries() {
    return this._queries;
  }

  _parseUnquotedQuery(query) {
    return query.replace(/\\(.)/g, '$1');
  }

  _parseQuotedQuery(query) {
    return query.substring(1, query.length - 1).replace(/\\(.)/g, '$1');
  }

  /**
   * @param {string} query
   * @return {?Search.SearchConfig.QueryTerm}
   */
  _parseFileQuery(query) {
    const match = query.match(FilePatternRegex);
    if (!match) {
      return null;
    }
    const isNegative = !!match[1];
    query = match[3];
    let result = '';
    for (let i = 0; i < query.length; ++i) {
      const char = query[i];
      if (char === '*') {
        result += '.*';
      } else if (char === '\\') {
        ++i;
        const nextChar = query[i];
        if (nextChar === ' ') {
          result += ' ';
        }
      } else {
        if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1) {
          result += '\\';
        }
        result += query.charAt(i);
      }
    }
    return new QueryTerm(result, isNegative);
  }
}

// After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
export const FilePatternRegex = /(-)?f(ile)?:((?:[^\\ ]|\\.)+)/;

export class QueryTerm {
  /**
   * @param {string} text
   * @param {boolean} isNegative
   */
  constructor(text, isNegative) {
    this.text = text;
    this.isNegative = isNegative;
  }
}

/**
 * @interface
 */
export class SearchResult {
  /**
   * @return {string}
   */
  label() {
  }

  /**
   * @return {string}
   */
  description() {
  }

  /**
   * @return {number}
   */
  matchesCount() {
  }

  /**
   * @param {number} index
   * @return {string}
   */
  matchLabel(index) {
  }

  /**
   * @param {number} index
   * @return {string}
   */
  matchLineContent(index) {
  }

  /**
   * @param {number} index
   * @return {!Object}
   */
  matchRevealable(index) {}
}

/**
 * @interface
 */
export class SearchScope {
  /**
   * @param {!Search.SearchConfig} searchConfig
   * @param {!Common.Progress} progress
   * @param {function(!Search.SearchResult)} searchResultCallback
   * @param {function(boolean)} searchFinishedCallback
   */
  performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {
  }

  /**
   * @param {!Common.Progress} progress
   */
  performIndexing(progress) {
  }

  stopSearch() {}
}

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

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

/**
 * @constructor
 */
Search.SearchConfig = SearchConfig;

/** @typedef {!{regex: !RegExp, isNegative: boolean}} */
Search.SearchConfig.RegexQuery;
Search.SearchConfig.FilePatternRegex = FilePatternRegex;

/**
 * @constructor
 */
Search.SearchConfig.QueryTerm = QueryTerm;

/**
 * @interface
 */
Search.SearchResult = SearchResult;

/**
 * @interface
 */
Search.SearchScope = SearchScope;
