// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
# Filter language

This language allows us to filter logs based on a set of conditions. The language is designed to
map directly to UI chip elements.

## Examples

1. Show logs of severity info or higher for entries where the moniker is `core/ffx-laboratory:hello`
   or the message contains “hello”.

  ```
  (moniker:core/ffx-laboratory:hello | message:hello) severity:info
  ```

2. Show logs of severity error or higher, where the component url contains a package named hello,
   where the manifest is named hello or where the message contains “hello world” but where the
   message doesn’t contain “bye”.

  ```
  (package_name:hello | manifest:hello | message:"hello world") severity:error !message:"bye"
  ```

3. Show logs from both core/foo and core/bar

  ```
  moniker:core/foo|core/bar

  # which is the same as:
  moniker:core/foo|moniker:core/bar
  ```

4. Show logs where any field contains foo, bar or baz either in the message, url, moniker, etc.

  ```
  any:foo|bar|baz
  ```

## Grammar

```
<operation> := <filter group> | <filter group> <and> <operation>

<filter group> := <single filter> | (<filter disjunction>)

<filter disjunction> := <single filter>
    | <not> <single filter>
    | <single filter> <or> <filter disjunction>

<single filter> := <category> <core operator> <core operator values>
    | severity <operator> <severity>
    | <pid tid category> <core operator> <numbers>
    | <custom key> <operator> <custom key values>
    | <regex>
    | <string>

<core operator> := <contains> | <equality>
<operator> := <contains> | <equality> | <comparison>
<contains> := ':'
<equality> := '='
<comparison> :=  '>' | '<' | '>=' | '<='

<category> := moniker | tag | package_name | manifest | message | any
<pid tid category> := pid | tid

<custom key values> := <numbers> | <boolean> | <regex> | <strings>
<core operator values> := <regex> | <strings>

<severity> := trace | debug | info | warn | error | fatal

<boolean> := true | false

<regex> := '/' <chars with spaces> '/'

<strings> := <string> | <string> '|' <strings>
<string> := <chars> | "<chars with spaces>"

<chars> := any sequence of characters without space
<chars with spaces> := any sequence of characters with spaces

<numbers>  := <number> | <number> '|' <numbers>
<number> := any sequence of numbers, including negative, exp, etc

<or> := '|' | or
<not> := not | '!'
<and> := and | '&' | ε   # just writing a space will be interpreted as AND in the top level
```

The severities, logical operators, categories are case insensitive. When doing a `:` (contains)
operation, the value being matched against will be treated as case insensitive.

The following categories are supported:

1. Moniker: identifies the component that emitted the log.

2. Tag: a log entry might contain one or more tags in its metadata.

3. Package name: The name of the package present in the corresponding section of the url with
    which the component was launched. Supported operations:

4. Manifest: The name of the manifest present in the corresponding section of the url with which
    the component was launched.

5. Message: The log message.

6. Severity: The severity of the log.

7. Pid and Tid: the process and thread ids that emitted the log.

8. Custom key: A structured field contained in the payload of a structured log.

9. Any: Matches a value in any of the previous sections.

All categories support `=`(equals) and `:` (contains). The `:` operator will do substring search,
equality when dealing with numbers of booleans or a minimum severity operation when applied to
`severity`. Custom keys and severities also support `>`, `<`, `>=`, `<=`, `=`.
*/

Expression
  = head:FilterGroup tail:(_ (And _)? FilterGroup)* {
    return tail.reduce((result, element) => {
      return result.concat([element[2]]);
    }, [head]);
  }

FilterGroup
  = "(" _ head:Filter tail:(_ Or _ Filter)* _ ")" {
    let group = tail.reduce((result, element) => {
      return result.concat(element[3]);
    }, [head])
    return group;
  }
  / filter:Filter { return [filter]; }


Filter
  = Not _ single:SingleFilter {
    single.not = true;
    return single;
  }
  / single:SingleFilter { return single; }

SingleFilter
  = "severity"i operator:Operator severities:Severities {
    return {
      category: 'severity',
        subCategory: undefined,
        operator: operator,
        values: severities,
        not: false
    };
  }
  / category:Category operator:CoreOperator strings:CoreOperatorValues {
    return {
      category: category,
      subCategory: undefined,
      operator: operator,
      values: strings,
      not: false,
    };
  }
  / category:PidTidCategory operator:CoreOperator numbers:Numbers {
    return {
      category: category,
      subCategory: undefined,
      operator: operator,
      values: numbers,
      not: false,
    }
  }
  / customKey:CustomKey operator:Operator values:CustomKeyValues {
    return {
      category: 'custom',
        subCategory: customKey,
        operator: operator,
        values: values,
        not: false
    }
  }
  / regex:Regex {
    return {
      category: 'any',
      subCategory: undefined,
      operator: 'contains',
      values: [regex],
      not: false,
    }
  }
  / string:String {
    return {
      category: 'any',
      subCategory: undefined,
      operator: 'contains',
      values: [string],
      not: false,
    }
  };

// NOTE: the returned types must match the ones in the Operator type in filter.ts.
CoreOperator
  = ":" { return 'contains'; }
  / "=" { return 'equal'; }

// NOTE: the returned types must match the ones in the Operator type in filter.ts.
Operator
  = ":" { return 'contains'; }
  / "=" { return 'equal'; }
  / ">=" { return 'greaterEq'; }
  / ">" { return 'greater'; }
  / "<=" { return 'lessEq'; }
  / "<" { return 'less'; }

// NOTE: the returned types must match the ones in the Category type in filter.ts.
Category
  = "any"i
  / "custom"i
  / "manifest"i
  / "message"i
  / "moniker"i
  / "package-name"i
  / "tag"i;

PidTidCategory
  = "pid"i
  / "tid"i;

CustomKeyValues
  = Numbers
  / b:Boolean { return [b]; }
  / r:Regex { return [r]; }
  / Strings

CoreOperatorValues
= r:Regex { return [r]; }
/ Strings

Severities
  = head:Severity tail:("|" Severities)* {
    return tail.reduce((result, element) => {
      return result.concat(element[1]);
    }, [head]);
  }

// NOTE: the returned types must match the ones in the Severity type in filter.ts.
Severity
  = "trace"i
  / "debug"i
  / "info"i
  / "warning"i { return "warn"; }
  / "warn"i
  / "error"i
  / "fatal"i

Boolean
  = "true"i { return true; }
  / "false"i { return false; }

Regex = "/" chars:RegexChar* "/" {
  return new RegExp(chars.join(""));
}

RegexChar
  = [^/\\]
  / "\\/" { return "/"; }
  / "\\\\" { return "\\"; }

Strings
  = head:String tail:("|" Strings)* {
    return tail.reduce((result, element) => {
      return result.concat(element[1]);
    }, [head]);
  }

CustomKey = [^:\\|\\(\\)><=" ]+ { return text(); }

Numbers
  = head:Number tail:("|" Numbers)* {
    return tail.reduce((result, element) => {
      return result.concat(element[1]);
    }, [head]);
}

// TODO(fxbug.dev/99486): support floating point, exponentials.
Number
  = [0-9]+ { return parseInt(text(), 10); }

String
  = '"' chars:CharWithinQuotes* '"' {
    return chars.join('');
  }
  /  chars:CharNotInQuotes+ { return chars.join(''); }

CharWithinQuotes
  = [^"\\]
  / '\\"' { return '"'; }
  / "\\\\" { return "\\"; }

CharNotInQuotes
  = [^"\\|\\(\\): ]
  / "\\" char:(
      '"'
    / '\\'
    / '('
    / ')'
    / ':'
    / ' '
  ) {
    return char;
  }

Not = "!" / "not"i
And = "&" / "and"i
Or = "|" / "or"i

// Whitespace
_ = [ \t\n\r]*
