// 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> <strings>
    | severity <operator> <severity>
    | <pid tid category> <core operator> <numbers>
    | <custom key> <operator> <custom key values>
    | <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> | <strings> | <boolean>

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

<boolean> := true | false

<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:Strings {
    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
    }
  }
  / 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]; }
  / 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
  / "warn"i
  / "error"i
  / "fatal"i

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

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
  = [^"\\|\\(\\): ]+ { return text(); }
  / '"' [^"]+ '"' {
    let t = text();
    return t.slice(1, t.length - 1);
  }

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

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