// Copyright (c) 2013 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.

var SourceFilterParser = (function() {
  'use strict';

  /**
   * Parses |filterText|, extracting a sort method, a list of filters, and a
   * copy of |filterText| with all sort parameters removed.
   */
  function SourceFilterParser(filterText) {
    // Final output will be stored here.
    this.filter = null;
    this.sort = {};
    this.filterTextWithoutSort = '';
    var filterList = parseFilter_(filterText);

    // Text filters are stored here as strings and then added as a function at
    // the end, for performance reasons.
    var textFilters = [];

    // Filter functions are first created individually, and then merged.
    var filterFunctions = [];

    for (var i = 0; i < filterList.length; ++i) {
      var filterElement = filterList[i].parsed;
      var negated = filterList[i].negated;

      var sort = parseSortDirective_(filterElement, negated);
      if (sort) {
        this.sort = sort;
        continue;
      }

      this.textWithoutSort += filterList[i].original;

      var filter = parseRestrictDirective_(filterElement, negated);
      if (!filter)
        filter = parseStringDirective_(filterElement, negated);
      if (filter) {
        if (negated) {
          filter = (function(func, sourceEntry) {
            return !func(sourceEntry);
          }).bind(null, filter);
        }
        filterFunctions.push(filter);
        continue;
      }
      textFilters.push({ text: filterElement, negated: negated });
    }

    // Create a single filter for all text filters, so they can share a
    // TabePrinter.
    filterFunctions.push(textFilter_.bind(null, textFilters));

    // Create function to go through all the filters.
    this.filter = function(sourceEntry) {
      for (var i = 0; i < filterFunctions.length; ++i) {
        if (!filterFunctions[i](sourceEntry))
          return false;
      }
      return true;
    };
  }

  /**
   * Parses a single "sort:" directive, and returns a dictionary containing
   * the sort function and direction.  Returns null on failure, including
   * the case when no such sort function exists.
   */
  function parseSortDirective_(filterElement, backwards) {
    var match = /^sort:(.*)$/.exec(filterElement);
    if (!match)
      return null;
    return { method: match[1], backwards: backwards };
  }

  /**
   * Tries to parses |filterElement| as a single "is:" directive, and returns a
   * new filter function.  Returns null on failure.
   */
  function parseRestrictDirective_(filterElement) {
    var match = /^is:(.*)$/.exec(filterElement);
    if (!match)
      return null;
    if (match[1] == 'active') {
      return function(sourceEntry) { return !sourceEntry.isInactive(); };
    }
    if (match[1] == 'error') {
      return function(sourceEntry) { return sourceEntry.isError(); };
    }
    return null;
  }

  /**
   * Tries to parse |filterElement| as a single filter of a type that takes
   * arbitrary strings as input, and returns a new filter function on success.
   * Returns null on failure.
   */
  function parseStringDirective_(filterElement) {
    var match = RegExp('^([^:]*):(.*)$').exec(filterElement);
    if (!match)
      return null;

    // Split parameters around commas and remove empty elements.
    var parameters = match[2].split(',');
    parameters = parameters.filter(function(string) {
      return string.length > 0;
    });

    if (match[1] == 'type') {
      return function(sourceEntry) {
        var i;
        var sourceType = sourceEntry.getSourceTypeString().toLowerCase();
        for (i = 0; i < parameters.length; ++i) {
          if (sourceType.search(parameters[i]) != -1)
            return true;
        }
        return false;
      };
    }

    if (match[1] == 'id') {
      return function(sourceEntry) {
        return parameters.indexOf(sourceEntry.getSourceId() + '') != -1;
      };
    }

    return null;
  }

  /**
   * Takes in the text of a filter and returns a list of
   * {parsed, original, negated} values that correspond to substrings of the
   * filter before and after filtering, and whether or not it started with a
   * '-'.  Extra whitespace other than a single character after each element is
   * ignored.  Parsed strings are all lowercase.
   */
  function parseFilter_(filterText) {
    // Assemble a list of quoted and unquoted strings in the filter.
    var filterList = [];
    var position = 0;
    while (position < filterText.length) {
      var inQuote = false;
      var filterElement = '';
      var negated = false;
      var startPosition = position;
      while (position < filterText.length) {
        var nextCharacter = filterText[position];
        ++position;
        if (nextCharacter == '\\' &&
            position < filterText.length) {
          // If there's a backslash, skip the backslash and add the next
          // character to the element.
          filterElement += filterText[position];
          ++position;
          continue;
        } else if (nextCharacter == '"') {
          // If there's an unescaped quote character, toggle |inQuote| without
          // modifying the element.
          inQuote = !inQuote;
        } else if (!inQuote && /\s/.test(nextCharacter)) {
          // If not in a quote and have a whitespace character, that's the
          // end of the element.
          break;
        } else if (nextCharacter == '-' && startPosition == position - 1) {
          // If this is the first character, and it's a '-', this entry is
          // negated.
          negated = true;
        } else {
          // Otherwise, add the next character to the element.
          filterElement += nextCharacter;
        }
      }

      if (filterElement.length > 0) {
        var filter = {
          parsed: filterElement.toLowerCase(),
          original: filterText.substring(startPosition, position),
          negated: negated,
        };
        filterList.push(filter);
      }
    }
    return filterList;
  }

  /**
   * Takes in a list of text filters and a SourceEntry.  Each filter has
   * "text" and "negated" fields.  Returns true if the SourceEntry matches all
   * filters in the (possibly empty) list.
   */
  function textFilter_(textFilters, sourceEntry) {
    var tablePrinter = null;
    for (var i = 0; i < textFilters.length; ++i) {
      var text = textFilters[i].text;
      var negated = textFilters[i].negated;
      var match = false;
      // The description is often not contained in one of the log entries.
      // The source type almost never is, so check for them directly.
      var description = sourceEntry.getDescription().toLowerCase();
      var type = sourceEntry.getSourceTypeString().toLowerCase();
      if (description.indexOf(text) != -1 || type.indexOf(text) != -1) {
        match = true;
      } else {
        if (!tablePrinter) {
          tablePrinter = createLogEntryTablePrinter(
              sourceEntry.getLogEntries(),
              SourceTracker.getInstance().getPrivacyStripping());
        }
        match = tablePrinter.search(text);
      }
      if (negated)
        match = !match;
      if (!match)
        return false;
    }
    return true;
  }

  return SourceFilterParser;
})();
