# Copyright 2016 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 or at
# https://developers.google.com/open-source/licenses/bsd

"""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 proto 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)
