# 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

"""Helper functions for sorting lists of project artifacts.

This module exports the SortArtifacts function that does sorting of
Monorail business objects (e.g., an issue).  The sorting is done by
extracting relevant values from the PB using a dictionary of
accessor functions.

The desired sorting directives are specified in part of the user's
HTTP request.  This sort spec consists of the names of the columns
with optional minus signs to indicate descending sort order.

The tool configuration object also affects sorting.  When sorting by
key-value labels, the well-known labels are considered to come
before any non-well-known labels, and those well-known labels sort in
the order in which they are defined in the tool config PB.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

from functools import total_ordering

import settings
from proto import tracker_pb2
from services import caches
from tracker import tracker_bizobj
from tracker import tracker_constants


@total_ordering
class DescendingValue(object):
  """A wrapper which reverses the sort order of values."""

  @classmethod
  def MakeDescendingValue(cls, obj):
    """Make a value that sorts in the reverse order as obj."""
    if isinstance(obj, int):
      return -obj
    if obj == MAX_STRING:
      return MIN_STRING
    if obj == MIN_STRING:
      return MAX_STRING
    if isinstance(obj, list):
      return [cls.MakeDescendingValue(item) for item in reversed(obj)]
    return DescendingValue(obj)

  def __init__(self, val):
    self.val = val

  def __eq__(self, other):
    if isinstance(other, DescendingValue):
      return self.val == other.val
    return self.val == other

  def __ne__(self, other):
    if isinstance(other, DescendingValue):
      return self.val != other.val
    return self.val != other

  def __lt__(self, other):
    if isinstance(other, DescendingValue):
      return other.val < self.val
    return other < self.val

  def __repr__(self):
    return 'DescendingValue(%r)' % self.val


# A string that sorts after every other string, and one that sorts before them.
MAX_STRING = '~~~'
MIN_STRING = DescendingValue(MAX_STRING)


# RAMCache {issue_id: {column_name: sort_key, ...}, ...}
art_values_cache = None


def InitializeArtValues(services):
  global art_values_cache
  art_values_cache = caches.RamCache(
      services.cache_manager, 'issue', max_size=settings.issue_cache_max_size)


def InvalidateArtValuesKeys(cnxn, keys):
  art_values_cache.InvalidateKeys(cnxn, keys)


def SortArtifacts(
    artifacts, config, accessors, postprocessors, group_by_spec, sort_spec,
    users_by_id=None, tie_breakers=None):
  """Return a list of artifacts sorted by the user's sort specification.

  In the following, an "accessor" is a function(art) -> [field_value, ...].

  Args:
    artifacts: an unsorted list of project artifact PBs.
    config: Project config PB instance that defines the sort order for
        labels and statuses in this project.
    accessors: dict {column_name: accessor} to get values from the artifacts.
    postprocessors: dict {column_name: postprocessor} to get user emails
        and timestamps.
    group_by_spec: string that lists the grouping order
    sort_spec: string that lists the sort order
    users_by_id: optional dictionary {user_id: user_view,...} for all users
        who participate in the list of artifacts.
    tie_breakers: list of column names to add to the end of the sort
        spec if they are not already somewhere in the sort spec.

  Returns:
    A sorted list of artifacts.

  Note: if username_cols is supplied, then users_by_id should be too.

  The approach to sorting is to construct a comprehensive sort key for
  each artifact. To create the sort key, we (a) build lists with a
  variable number of fields to sort on, and (b) allow individual
  fields to be sorted in descending order.  Even with the time taken
  to build the sort keys, calling sorted() with the key seems to be
  faster overall than doing multiple stable-sorts or doing one sort
  using a multi-field comparison function.
  """
  sort_directives = ComputeSortDirectives(
      config, group_by_spec, sort_spec, tie_breakers=tie_breakers)

  # Build a list of accessors that will extract sort keys from the issues.
  accessor_pairs = [
      (sd, _MakeCombinedSortKeyAccessor(
          sd, config, accessors, postprocessors, users_by_id))
      for sd in sort_directives]

  def SortKey(art):
    """Make a sort_key for the given artifact, used by sorted() below."""
    if art_values_cache.HasItem(art.issue_id):
      art_values = art_values_cache.GetItem(art.issue_id)
    else:
      art_values = {}

    sort_key = []
    for sd, accessor in accessor_pairs:
      if sd not in art_values:
        art_values[sd] = accessor(art)
      sort_key.append(art_values[sd])

    art_values_cache.CacheItem(art.issue_id, art_values)
    return sort_key

  return sorted(artifacts, key=SortKey)


def ComputeSortDirectives(config, group_by_spec, sort_spec, tie_breakers=None):
  """Return a list with sort directives to be used in sorting.

  Args:
    config: Project config PB instance that defines the sort order for
        labels and statuses in this project.
    group_by_spec: string that lists the grouping order
    sort_spec: string that lists the sort order
    tie_breakers: list of column names to add to the end of the sort
        spec if they are not already somewhere in the sort spec.

  Returns:
    A list of lower-case column names, each one may have a leading
    minus-sign.
  """
  # Prepend the end-user's sort spec to any project default sort spec.
  if tie_breakers is None:
    tie_breakers = ['id']
  sort_spec = '%s %s %s' % (
      group_by_spec, sort_spec, config.default_sort_spec)
  # Sort specs can have interfering sort orders, so remove any duplicates.
  field_names = set()
  sort_directives = []
  for sort_directive in sort_spec.lower().split():
    field_name = sort_directive.lstrip('-')
    if field_name not in field_names:
      sort_directives.append(sort_directive)
      field_names.add(field_name)

  # Add in the project name so that the overall ordering is completely
  # defined in cross-project search. Otherwise, issues jump up and
  # down on each reload of the same query, and prev/next links get
  # messed up.  It's a no-op in single projects.
  if 'project' not in sort_directives:
    sort_directives.append('project')

  for tie_breaker in tie_breakers:
    if tie_breaker not in sort_directives:
      sort_directives.append(tie_breaker)

  return sort_directives


def _MakeCombinedSortKeyAccessor(
    sort_directive, config, accessors, postprocessors, users_by_id):
  """Return an accessor that extracts a sort key for a UI table column.

  Args:
    sort_directive: string with column name and optional leading minus sign,
        for combined columns, it may have slashes, e.g., "-priority/pri".
    config: ProjectIssueConfig instance that defines the sort order for
        labels and statuses in this project.
    accessors: dictionary of (column_name -> accessor) to get values
        from the artifacts.
    postprocessors: dict {column_name: postprocessor} to get user emails
        and timestamps.
    users_by_id: dictionary {user_id: user_view,...} for all users
        who participate in the list of artifacts (e.g., owners, reporters, cc).

  Returns:
    A list of accessor functions that can be applied to an issue to extract
    the relevant sort key value.

  The strings for status and labels are converted to lower case in
  this method so that they sort like case-insensitive enumerations.
  Any component-specific field of the artifact is sorted according to the
  value returned by the accessors defined in that component.  Those
  accessor functions should lower case string values for fields where
  case-insensitive sorting is desired.
  """
  if sort_directive.startswith('-'):
    combined_col_name = sort_directive[1:]
    descending = True
  else:
    combined_col_name = sort_directive
    descending = False

  wk_labels = [wkl.label for wkl in config.well_known_labels]
  accessors = [
      _MakeSingleSortKeyAccessor(
          col_name, config, accessors, postprocessors, users_by_id, wk_labels)
      for col_name in combined_col_name.split('/')]

  # The most common case is that we sort on a single column, like "priority".
  if len(accessors) == 1:
    return _MaybeMakeDescending(accessors[0], descending)

  # Less commonly, we are sorting on a combined column like "priority/pri".
  def CombinedAccessor(art):
    """Flatten and sort the values for each column in a combined column."""
    key_part = []
    for single_accessor in accessors:
      value = single_accessor(art)
      if isinstance(value, list):
        key_part.extend(value)
      else:
        key_part.append(value)
    return sorted(key_part)

  return _MaybeMakeDescending(CombinedAccessor, descending)


def _MaybeMakeDescending(accessor, descending):
  """If descending is True, return a new function that reverses accessor."""
  if not descending:
    return accessor

  def DescendingAccessor(art):
    asc_value = accessor(art)
    return DescendingValue.MakeDescendingValue(asc_value)

  return DescendingAccessor


def _MakeSingleSortKeyAccessor(
    col_name, config, accessors, postprocessors, users_by_id, wk_labels):
  """Return an accessor function for a single simple UI column."""
  # Case 1. Handle built-in fields: status, component.
  if col_name == 'status':
    wk_statuses = [wks.status for wks in config.well_known_statuses]
    return _IndexOrLexical(wk_statuses, accessors[col_name])

  if col_name == 'component':
    comp_defs = sorted(config.component_defs, key=lambda cd: cd.path.lower())
    comp_ids = [cd.component_id for cd in comp_defs]
    return _IndexListAccessor(comp_ids, accessors[col_name])

  # Case 2. Any other defined accessor functions.
  if col_name in accessors:
    if postprocessors and col_name in postprocessors:
      # sort users by email address or timestamp rather than user ids.
      return _MakeAccessorWithPostProcessor(
          users_by_id, accessors[col_name], postprocessors[col_name])
    else:
      return accessors[col_name]

  # Case 3. Anything else is assumed to be a label prefix or custom field.
  return _IndexOrLexicalList(
      wk_labels, config.field_defs, col_name, users_by_id)


IGNORABLE_INDICATOR = -1


def _PrecomputeSortIndexes(values, col_name):
  """Precompute indexes of strings in the values list for fast lookup later."""
  # Make a dictionary that immediately gives us the index of any value
  # in the list, and also add the same values in all-lower letters.  In
  # the case where two values differ only by case, the later value wins,
  # which is fine.
  indexes = {}
  if col_name:
    prefix = col_name + '-'
  else:
    prefix = ''
  for idx, val in enumerate(values):
    if val.lower().startswith(prefix):
      indexes[val] = idx
      indexes[val.lower()] = idx
    else:
      indexes[val] = IGNORABLE_INDICATOR
      indexes[val.lower()] = IGNORABLE_INDICATOR

  return indexes


def _MakeAccessorWithPostProcessor(users_by_id, base_accessor, postprocessor):
  """Make an accessor that returns a list of user_view properties for sorting.

  Args:
    users_by_id: dictionary {user_id: user_view, ...} for all participants
        in the entire list of artifacts.
    base_accessor: an accessor function f(artifact) -> user_id.
    postprocessor: function f(user_view) -> single sortable value.

  Returns:
    An accessor f(artifact) -> value that can be used in sorting
    the decorated list.
  """

  def Accessor(art):
    """Return a user edit name for the given artifact's base_accessor."""
    id_or_id_list = base_accessor(art)
    if isinstance(id_or_id_list, list):
      values = [postprocessor(users_by_id[user_id])
                for user_id in id_or_id_list]
    else:
      values = [postprocessor(users_by_id[id_or_id_list])]

    return sorted(values) or MAX_STRING

  return Accessor


def _MakeColumnAccessor(col_name):
  """Make an accessor for an issue's labels that have col_name as a prefix.

  Args:
    col_name: string column name.

  Returns:
    An accessor that can be applied to an artifact to return a list of
    labels that have col_name as a prefix.

  For example, _MakeColumnAccessor('priority')(issue) could result in
  [], or ['priority-high'], or a longer list for multi-valued labels.
  """
  prefix = col_name + '-'

  def Accessor(art):
    """Return a list of label values on the given artifact."""
    result = [label.lower() for label in tracker_bizobj.GetLabels(art)
              if label.lower().startswith(prefix)]
    return result

  return Accessor


def _IndexOrLexical(wk_values, base_accessor):
  """Return an accessor to score an artifact based on a user-defined ordering.

  Args:
    wk_values: a list of well-known status values from the config.
    base_accessor: function that gets a field from a given issue.

  Returns:
    An accessor that can be applied to an issue to return a suitable
    sort key.

  For example, when used to sort issue statuses, these accessors return an
  integer for well-known statuses, a string for odd-ball statuses, and an
  extreme value key for issues with no status.  That causes issues to appear
  in the expected order with odd-ball issues sorted lexicographically after
  the ones with well-known status values, and issues with no defined status at
  the very end.
  """
  well_known_value_indexes = _PrecomputeSortIndexes(wk_values, '')

  def Accessor(art):
    """Custom-made function to return a specific value of any issue."""
    value = base_accessor(art)
    if not value:
      # Undefined values sort last.
      return MAX_STRING

    try:
      # Well-known values sort by index.  Ascending sorting has positive ints
      # in well_known_value_indexes.
      return well_known_value_indexes[value]
    except KeyError:
      # Odd-ball values after well-known and lexicographically.
      return value.lower()

  return Accessor


def _IndexListAccessor(wk_values, base_accessor):
  """Return an accessor to score an artifact based on a user-defined ordering.

  Args:
    wk_values: a list of well-known values from the config.
    base_accessor: function that gets a field from a given issue.

  Returns:
    An accessor that can be applied to an issue to return a suitable
    sort key.
  """
  well_known_value_indexes = {
    val: idx for idx, val in enumerate(wk_values)}

  def Accessor(art):
    """Custom-made function to return a specific value of any issue."""
    values = base_accessor(art)
    if not values:
      # Undefined values sort last.
      return MAX_STRING

    indexes = [well_known_value_indexes.get(val, MAX_STRING) for val in values]
    return sorted(indexes)

  return Accessor


def _IndexOrLexicalList(wk_values, full_fd_list, col_name, users_by_id):
  """Return an accessor to score an artifact based on a user-defined ordering.

  Args:
    wk_values: A list of well-known labels from the config.
    full_fd_list: list of FieldDef PBs that belong to the config.
    col_name: lowercase string name of the column that will be sorted on.
    users_by_id: A dictionary {user_id: user_view}.

  Returns:
    An accessor that can be applied to an issue to return a suitable
    sort key.
  """
  well_known_value_indexes = _PrecomputeSortIndexes(wk_values, col_name)

  if col_name.endswith(tracker_constants.APPROVER_COL_SUFFIX):
    # Custom field names cannot end with the APPROVER_COL_SUFFIX. So the only
    # possible relevant values are approvers for an APPROVAL_TYPE named
    # field_name and any values from labels with the key 'field_name-approvers'.
    field_name = col_name[:-len(tracker_constants.APPROVER_COL_SUFFIX)]
    approval_fds = [fd for fd in full_fd_list
                    if (fd.field_name.lower() == field_name and
                        fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE)]

    def ApproverAccessor(art):
      """Custom-made function to return a sort value or an issue's approvers."""
      idx_or_lex_list = (
          _SortableApprovalApproverValues(art, approval_fds, users_by_id) +
          _SortableLabelValues(art, col_name, well_known_value_indexes))
      if not idx_or_lex_list:
        return MAX_STRING  # issues with no value sort to the end of the list.
      return sorted(idx_or_lex_list)

    return ApproverAccessor

  # Column name does not end with APPROVER_COL_SUFFIX, so relevant values
  # are Approval statuses or Field Values for fields named col_name and
  # values from labels with the key equal to col_name.
  field_name = col_name
  phase_name = None
  if '.' in col_name:
    phase_name, field_name = col_name.split('.', 1)

  fd_list = [fd for fd in full_fd_list
             if (fd.field_name.lower() == field_name and
                 fd.field_type != tracker_pb2.FieldTypes.ENUM_TYPE and
                 bool(phase_name) == fd.is_phase_field)]
  approval_fds = []
  if not phase_name:
    approval_fds = [fd for fd in fd_list if
                    fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE]

  def Accessor(art):
    """Custom-made function to return a sort value for any issue."""
    idx_or_lex_list = (
        _SortableApprovalStatusValues(art, approval_fds) +
        _SortableFieldValues(art, fd_list, users_by_id, phase_name) +
        _SortableLabelValues(art, col_name, well_known_value_indexes))
    if not idx_or_lex_list:
      return MAX_STRING  # issues with no value sort to the end of the list.
    return sorted(idx_or_lex_list)

  return Accessor


def _SortableApprovalStatusValues(art, fd_list):
  """Return a list of approval statuses relevant to one UI table column."""
  sortable_value_list = []
  for fd in fd_list:
    for av in art.approval_values:
      if av.approval_id == fd.field_id:
        # Order approval statuses by life cycle.
        # NOT_SET == 8 but should be before all other statuses.
        sortable_value_list.append(
            0 if av.status.number == 8 else av.status.number)

  return sortable_value_list


def _SortableApprovalApproverValues(art, fd_list, users_by_id):
  """Return a list of approval approvers relevant to one UI table column."""
  sortable_value_list = []
  for fd in fd_list:
    for av in art.approval_values:
      if av.approval_id == fd.field_id:
        sortable_value_list.extend(
          [users_by_id.get(approver_id).email
           for approver_id in av.approver_ids
           if users_by_id.get(approver_id)])

  return sortable_value_list


def _SortableFieldValues(art, fd_list, users_by_id, phase_name):
  """Return a list of field values relevant to one UI table column."""
  phase_id = None
  if phase_name:
    phase_id = next((
        phase.phase_id for phase in art.phases
        if phase.name.lower() == phase_name), None)
  sortable_value_list = []
  for fd in fd_list:
    for fv in art.field_values:
      if fv.field_id == fd.field_id and fv.phase_id == phase_id:
        sortable_value_list.append(
            tracker_bizobj.GetFieldValue(fv, users_by_id))

  return sortable_value_list


def _SortableLabelValues(art, col_name, well_known_value_indexes):
  """Return a list of ints and strings for labels relevant to one UI column."""
  col_name_dash = col_name + '-'
  sortable_value_list = []
  for label in tracker_bizobj.GetLabels(art):
    idx_or_lex = well_known_value_indexes.get(label)
    if idx_or_lex == IGNORABLE_INDICATOR:
      continue  # Label is known to not have the desired prefix.
    if idx_or_lex is None:
      if '-' not in label:
        # Skip an irrelevant OneWord label and remember to ignore it later.
        well_known_value_indexes[label] = IGNORABLE_INDICATOR
        continue
      label_lower = label.lower()
      if label_lower.startswith(col_name_dash):
        # Label is a key-value label with an odd-ball value, remember it
        value = label_lower[len(col_name_dash):]
        idx_or_lex = value
        well_known_value_indexes[label] = value
      else:
        # Label was a key-value label that is not relevant to this column.
        # Remember to ignore it later.
        well_known_value_indexes[label] = IGNORABLE_INDICATOR
        continue

    sortable_value_list.append(idx_or_lex)

  return sortable_value_list
