# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Protocol buffers for user queries parsed into abstract syntax trees.

A user issue query can look like [Type=Defect owner:jrobbins "memory leak"].
In that simple form, all the individual search conditions are simply ANDed
together.  In the code, a list of conditions to be ANDed is called a
conjunction.

Monorail also supports a quick-or feature: [Type=Defect,Enhancement].  That
will match any issue that has labels Type-Defect or Type-Enhancement, or both.

Monorail supports a top-level "OR" keyword that can
be used to logically OR a series of conjunctions.  For example:
[Type=Defect stars>10 OR Type=Enhancement stars>50].

Parentheses groups and "OR" statements are preprocessed before the final
QueryAST is constructed.

So, QueryAST is always exactly two levels:  the overall tree
consists of a list of conjunctions, and each conjunction consists of a list
of conditions.

A condition can look like [stars>10] or [summary:memory] or
[Type=Defect,Enhancement].  Each condition has a single comparison operator.
Most conditions refer to a single field definition, but in the case of
cross-project search a single condition can have a list of field definitions
from the different projects being searched.  Each condition can have a list
of constant values to compare against.  The values may be all strings or all
integers.

Some conditions are procesed by the SQL database and others by the GAE
search API.  All conditions are passed to each module and it is up to
the module to decide which conditions to handle and which to ignore.
"""

from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

from protorpc import messages

from mrproto import tracker_pb2


# This is a special field_name for a FieldDef that means to do a fulltext
# search for words that occur in any part of the issue.
ANY_FIELD = 'any_field'


class QueryOp(messages.Enum):
  """Enumeration of possible query condition operators."""
  EQ = 1
  NE = 2
  LT = 3
  GT = 4
  LE = 5
  GE = 6
  TEXT_HAS = 7
  NOT_TEXT_HAS = 8
  IS_DEFINED = 11
  IS_NOT_DEFINED = 12
  KEY_HAS = 13


class TokenType(messages.Enum):
  """Enumeration of query tokens used for parentheses parsing."""
  SUBQUERY = 1
  LEFT_PAREN = 2
  RIGHT_PAREN = 3
  OR = 4


class QueryToken(messages.Message):
  """Data structure to represent a single token for parentheses parsing."""
  token_type = messages.EnumField(TokenType, 1, required=True)
  value = messages.StringField(2)


class Condition(messages.Message):
  """Representation of one query condition.  E.g., [Type=Defect,Task]."""
  op = messages.EnumField(QueryOp, 1, required=True)
  field_defs = messages.MessageField(tracker_pb2.FieldDef, 2, repeated=True)
  str_values = messages.StringField(3, repeated=True)
  int_values = messages.IntegerField(4, repeated=True)
  # The suffix of a search field
  # eg. the 'approver' in 'UXReview-approver:user@mail.com'
  key_suffix = messages.StringField(5)
  # The name of the phase this field value should belong to.
  phase_name = messages.StringField(6)


class Conjunction(messages.Message):
  """A list of conditions that are implicitly ANDed together."""
  conds = messages.MessageField(Condition, 1, repeated=True)


class QueryAST(messages.Message):
  """Abstract syntax tree for the user's query."""
  conjunctions = messages.MessageField(Conjunction, 1, repeated=True)


def MakeCond(op, field_defs, str_values, int_values,
             key_suffix=None, phase_name=None):
  """Shorthand function to construct a Condition PB."""
  return Condition(
      op=op, field_defs=field_defs, str_values=str_values,
      int_values=int_values, key_suffix=key_suffix, phase_name=phase_name)
