# 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.

"""Classes and functions for displaying grids of project artifacts.

A grid is a two-dimensional display of items where the user can choose
the X and Y axes.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import ezt

import collections
import logging
import settings

from features import features_constants
from framework import framework_constants
from framework import sorting
from framework import table_view_helpers
from framework import template_helpers
from framework import urls
from mrproto import tracker_pb2
from tracker import tracker_bizobj
from tracker import tracker_constants
from tracker import tracker_helpers


# We shorten long attribute values to fit into the table cells.
_MAX_CELL_DISPLAY_CHARS = 70


def SortGridHeadings(col_name, heading_value_list, users_by_id, config,
                     asc_accessors):
  """Sort the grid headings according to well-known status and label order.

  Args:
    col_name: String column name that is used on that grid axis.
    heading_value_list: List of grid row or column heading values.
    users_by_id: Dict mapping user_ids to UserViews.
    config: ProjectIssueConfig PB for the current project.
    asc_accessors: Dict (col_name -> function()) for special columns.

  Returns:
    The same heading values, but sorted in a logical order.
  """
  decorated_list = []
  fd = tracker_bizobj.FindFieldDef(col_name, config)
  if fd and fd.field_type != tracker_pb2.FieldTypes.ENUM_TYPE:  # Handle fields.
    for value in heading_value_list:
      field_value = tracker_bizobj.GetFieldValueWithRawValue(
          fd.field_type, None, users_by_id, value)
      decorated_list.append([field_value, field_value])
  elif col_name == 'status':
    wk_statuses = [wks.status.lower()
                   for wks in config.well_known_statuses]
    decorated_list = [(_WKSortingValue(value.lower(), wk_statuses), value)
                      for value in heading_value_list]

  elif col_name in asc_accessors:  # Special cols still sort alphabetically.
    decorated_list = [(value, value)
                      for value in heading_value_list]

  else:  # Anything else is assumed to be a label prefix
    col_name_dash = col_name + '-'
    wk_labels = []
    for wkl in config.well_known_labels:
      lab_lower = wkl.label.lower()
      if lab_lower.startswith(col_name_dash):
        wk_labels.append(lab_lower.split('-', 1)[-1])
    decorated_list = [(_WKSortingValue(value.lower(), wk_labels), value)
                      for value in heading_value_list]

  decorated_list.sort()
  result = [decorated_tuple[1] for decorated_tuple in decorated_list]
  logging.info('Headers for %s are: %r', col_name, result)
  return result


def _WKSortingValue(value, well_known_list):
  """Return a value used to sort headings so that well-known ones are first."""
  if not value:
    return sorting.MAX_STRING  # Undefined values sort last.
  try:
    # well-known values sort by index
    return '%09d' % well_known_list.index(value)
  except ValueError:
    return value  # odd-ball values lexicographically after all well-known ones


def MakeGridData(
    artifacts, x_attr, x_headings, y_attr, y_headings, users_by_id,
    artifact_view_factory, all_label_values, config, related_issues,
    hotlist_context_dict=None):
  """Return a list of grid row items for display by EZT.

  Args:
    artifacts: a list of issues to consider showing.
    x_attr: lowercase name of the attribute that defines the x-axis.
    x_headings: list of values for column headings.
    y_attr: lowercase name of the attribute that defines the y-axis.
    y_headings: list of values for row headings.
    users_by_id: dict {user_id: user_view, ...} for referenced users.
    artifact_view_factory: constructor for grid tiles.
    all_label_values: pre-parsed dictionary of values from the key-value
        labels on each issue: {issue_id: {key: [val,...], ...}, ...}
    config: ProjectIssueConfig PB for the current project.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    hotlist_context_dict: dict{issue_id: {hotlist_item_field: field_value, ..}}

  Returns:
    A list of EZTItems, each representing one grid row, and each having
    a nested list of grid cells.

  Each grid row has a row name, and a list of cells.  Each cell has a
  list of tiles.  Each tile represents one artifact.  Artifacts are
  represented once in each cell that they match, so one artifact that
  has multiple values for a certain attribute can occur in multiple cells.
  """
  x_attr = x_attr.lower()
  y_attr = y_attr.lower()

  # A flat dictionary {(x, y): [cell, ...], ...] for the whole grid.
  x_y_data = collections.defaultdict(list)

  # Put each issue into the grid cell(s) where it belongs.
  for art in artifacts:
    if hotlist_context_dict:
      hotlist_issues_context = hotlist_context_dict[art.issue_id]
    else:
      hotlist_issues_context = None
    label_value_dict = all_label_values[art.local_id]
    x_vals = GetArtifactAttr(
        art, x_attr, users_by_id, label_value_dict, config, related_issues,
        hotlist_issue_context=hotlist_issues_context)
    y_vals = GetArtifactAttr(
        art, y_attr, users_by_id, label_value_dict, config, related_issues,
        hotlist_issue_context=hotlist_issues_context)
    tile = artifact_view_factory(art)

    # Put the current issue into each cell where it belongs, which will usually
    # be exactly 1 cell, but it could be a few.
    if x_attr != '--' and y_attr != '--':  # User specified both axes.
      for x in x_vals:
        for y in y_vals:
          x_y_data[x, y].append(tile)
    elif y_attr != '--':  # User only specified Y axis.
      for y in y_vals:
        x_y_data['All', y].append(tile)
    elif x_attr != '--':  # User only specified X axis.
      for x in x_vals:
        x_y_data[x, 'All'].append(tile)
    else:  # User specified neither axis.
      x_y_data['All', 'All'].append(tile)

  # Convert the dictionary to a list-of-lists so that EZT can iterate over it.
  grid_data = []
  i = 0
  for y in y_headings:
    cells_in_row = []
    for x in x_headings:
      tiles = x_y_data[x, y]
      for tile in tiles:
        tile.data_idx = i
        i += 1

      drill_down = ''
      if x_attr != '--':
        drill_down = MakeDrillDownSearch(x_attr, x)
      if y_attr != '--':
        drill_down += MakeDrillDownSearch(y_attr, y)

      cells_in_row.append(template_helpers.EZTItem(
          tiles=tiles, count=len(tiles), drill_down=drill_down))
    grid_data.append(template_helpers.EZTItem(
        grid_y_heading=y, cells_in_row=cells_in_row))

  return grid_data


def MakeDrillDownSearch(attr, value):
  """Constructs search term for drill-down.

  Args:
    attr: lowercase name of the attribute to narrow the search on.
    value: value to narrow the search to.

  Returns:
    String with user-query term to narrow a search to the given attr value.
  """
  if value == framework_constants.NO_VALUES:
    return '-has:%s ' % attr
  else:
    return '%s=%s ' % (attr, value)


def MakeLabelValuesDict(art):
  """Return a dict of label values and a list of one-word labels.

  Args:
    art: artifact object, e.g., an issue PB.

  Returns:
    A dict {prefix: [suffix,...], ...} for each key-value label.
  """
  label_values = collections.defaultdict(list)
  for label_name in tracker_bizobj.GetLabels(art):
    if '-' in label_name:
      key, value = label_name.split('-', 1)
      label_values[key.lower()].append(value)

  return label_values


def GetArtifactAttr(
    art, attribute_name, users_by_id, label_attr_values_dict,
    config, related_issues, hotlist_issue_context=None):
  """Return the requested attribute values of the given artifact.

  Args:
    art: a tracked artifact with labels, local_id, summary, stars, and owner.
    attribute_name: lowercase string name of attribute to get.
    users_by_id: dictionary of UserViews already created.
    label_attr_values_dict: dictionary {'key': [value, ...], }.
    config: ProjectIssueConfig PB for the current project.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    hotlist_issue_context: dict of {hotlist_issue_field: field_value,..}

  Returns:
    A list of string attribute values, or [framework_constants.NO_VALUES]
    if the artifact has no value for that attribute.
  """
  if attribute_name == '--':
    return []
  if attribute_name == 'id':
    return [art.local_id]
  if attribute_name == 'summary':
    return [art.summary]
  if attribute_name == 'status':
    return [tracker_bizobj.GetStatus(art)]
  if attribute_name == 'stars':
    return [art.star_count]
  if attribute_name == 'attachments':
    return [art.attachment_count]
  # TODO(jrobbins): support blocking
  if attribute_name == 'project':
    return [art.project_name]
  if attribute_name == 'mergedinto':
    if art.merged_into and art.merged_into != 0:
      return [tracker_bizobj.FormatIssueRef((
          related_issues[art.merged_into].project_name,
          related_issues[art.merged_into].local_id))]
    else:
      return [framework_constants.NO_VALUES]
  if attribute_name == 'blocked':
    return ['Yes' if art.blocked_on_iids else 'No']
  if attribute_name == 'blockedon':
    if not art.blocked_on_iids:
      return [framework_constants.NO_VALUES]
    else:
      return [tracker_bizobj.FormatIssueRef((
          related_issues[blocked_on_iid].project_name,
          related_issues[blocked_on_iid].local_id)) for
              blocked_on_iid in art.blocked_on_iids]
  if attribute_name == 'blocking':
    if not art.blocking_iids:
      return [framework_constants.NO_VALUES]
    return [tracker_bizobj.FormatIssueRef((
        related_issues[blocking_iid].project_name,
        related_issues[blocking_iid].local_id)) for
            blocking_iid in art.blocking_iids]
  if attribute_name == 'adder':
    if hotlist_issue_context:
      adder_id = hotlist_issue_context['adder_id']
      return [users_by_id[adder_id].display_name]
    else:
      return [framework_constants.NO_VALUES]
  if attribute_name == 'added':
    if hotlist_issue_context:
      return [hotlist_issue_context['date_added']]
    else:
      return [framework_constants.NO_VALUES]
  if attribute_name == 'reporter':
    return [users_by_id[art.reporter_id].display_name]
  if attribute_name == 'owner':
    owner_id = tracker_bizobj.GetOwnerId(art)
    if not owner_id:
      return [framework_constants.NO_VALUES]
    else:
      return [users_by_id[owner_id].display_name]
  if attribute_name == 'cc':
    cc_ids = tracker_bizobj.GetCcIds(art)
    if not cc_ids:
      return [framework_constants.NO_VALUES]
    else:
      return [users_by_id[cc_id].display_name for cc_id in cc_ids]
  if attribute_name == 'component':
    comp_ids = list(art.component_ids) + list(art.derived_component_ids)
    if not comp_ids:
      return [framework_constants.NO_VALUES]
    else:
      paths = []
      for comp_id in comp_ids:
        cd = tracker_bizobj.FindComponentDefByID(comp_id, config)
        if cd:
          paths.append(cd.path)
      return paths

  # Check to see if it is a field. Process as field only if it is not an enum
  # type because enum types are stored as key-value labels.
  fd = tracker_bizobj.FindFieldDef(attribute_name, config)
  if fd and fd.field_type != tracker_pb2.FieldTypes.ENUM_TYPE:
    values = []
    for fv in art.field_values:
      if fv.field_id == fd.field_id:
        value = tracker_bizobj.GetFieldValueWithRawValue(
            fd.field_type, fv, users_by_id, None)
        values.append(value)
    return values

  # Since it is not a built-in attribute or a field, it must be a key-value
  # label.
  return label_attr_values_dict.get(
      attribute_name, [framework_constants.NO_VALUES])


def AnyArtifactHasNoAttr(
    artifacts, attr_name, users_by_id, all_label_values, config,
    related_issues, hotlist_context_dict=None):
  """Return true if any artifact does not have a value for attr_name."""
  # TODO(jrobbins): all_label_values needs to be keyed by issue_id to allow
  # cross-project grid views.
  for art in artifacts:
    if hotlist_context_dict:
      hotlist_issue_context = hotlist_context_dict[art.issue_id]
    else:
      hotlist_issue_context = None
    vals = GetArtifactAttr(
        art, attr_name.lower(), users_by_id, all_label_values[art.local_id],
        config, related_issues, hotlist_issue_context=hotlist_issue_context)
    if framework_constants.NO_VALUES in vals:
      return True

  return False


def GetGridViewData(
    mr, results, config, users_by_id, starred_iid_set,
    grid_limited, related_issues, hotlist_context_dict=None):
  """EZT template values to render a Grid View of issues.
  Args:
    mr: commonly used info parsed from the request.
    results: The Issue PBs that are the search results to be displayed.
    config: The ProjectConfig PB for the project this view is in.
    users_by_id: A dictionary {user_id: user_view,...} for all the users
        involved in results.
    starred_iid_set: Set of issues that the user has starred.
    grid_limited: True if the results were limited to fit within the grid.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    hotlist_context_dict: dict for building a hotlist grid table

  Returns:
    Dictionary for EZT template rendering of the Grid View.
  """
  # We need ordered_columns because EZT loops have no loop-counter available.
  # And, we use column number in the Javascript to hide/show columns.
  columns = mr.col_spec.split()
  ordered_columns = [template_helpers.EZTItem(col_index=i, name=col)
                     for i, col in enumerate(columns)]
  other_built_in_cols = (features_constants.OTHER_BUILT_IN_COLS if
                         hotlist_context_dict else
                         tracker_constants.OTHER_BUILT_IN_COLS)
  unshown_columns = table_view_helpers.ComputeUnshownColumns(
      results, columns, config, other_built_in_cols)

  grid_x_attr = (mr.x or config.default_x_attr or '--').lower()
  grid_y_attr = (mr.y or config.default_y_attr or '--').lower()

  # Prevent the user from using an axis that we don't support.
  for bad_axis in tracker_constants.NOT_USED_IN_GRID_AXES:
    lower_bad_axis = bad_axis.lower()
    if grid_x_attr == lower_bad_axis:
      grid_x_attr = '--'
    if grid_y_attr == lower_bad_axis:
      grid_y_attr = '--'
  # Using the same attribute on both X and Y is not useful.
  if grid_x_attr == grid_y_attr:
    grid_x_attr = '--'

  all_label_values = {}
  for art in results:
    all_label_values[art.local_id] = (
        MakeLabelValuesDict(art))

  if grid_x_attr == '--':
    grid_x_headings = ['All']
  else:
    grid_x_items = table_view_helpers.ExtractUniqueValues(
        [grid_x_attr], results, users_by_id, config, related_issues,
        hotlist_context_dict=hotlist_context_dict)
    grid_x_headings = grid_x_items[0].filter_values
    if AnyArtifactHasNoAttr(
        results, grid_x_attr, users_by_id, all_label_values,
        config, related_issues, hotlist_context_dict= hotlist_context_dict):
      grid_x_headings.append(framework_constants.NO_VALUES)
    grid_x_headings = SortGridHeadings(
        grid_x_attr, grid_x_headings, users_by_id, config,
        tracker_helpers.SORTABLE_FIELDS)

  if grid_y_attr == '--':
    grid_y_headings = ['All']
  else:
    grid_y_items = table_view_helpers.ExtractUniqueValues(
        [grid_y_attr], results, users_by_id, config, related_issues,
        hotlist_context_dict=hotlist_context_dict)
    grid_y_headings = grid_y_items[0].filter_values
    if AnyArtifactHasNoAttr(
        results, grid_y_attr, users_by_id, all_label_values,
        config, related_issues, hotlist_context_dict= hotlist_context_dict):
      grid_y_headings.append(framework_constants.NO_VALUES)
    grid_y_headings = SortGridHeadings(
        grid_y_attr, grid_y_headings, users_by_id, config,
        tracker_helpers.SORTABLE_FIELDS)

  logging.info('grid_x_headings = %s', grid_x_headings)
  logging.info('grid_y_headings = %s', grid_y_headings)
  grid_data = PrepareForMakeGridData(
      results, starred_iid_set, grid_x_attr, grid_x_headings,
      grid_y_attr, grid_y_headings, users_by_id, all_label_values,
      config, related_issues, hotlist_context_dict=hotlist_context_dict)

  grid_axis_choice_dict = {}
  for oc in ordered_columns:
    grid_axis_choice_dict[oc.name] = True
  for uc in unshown_columns:
    grid_axis_choice_dict[uc] = True
  for bad_axis in tracker_constants.NOT_USED_IN_GRID_AXES:
    if bad_axis in grid_axis_choice_dict:
      del grid_axis_choice_dict[bad_axis]
  grid_axis_choices = list(grid_axis_choice_dict.keys())
  grid_axis_choices.sort()

  grid_cell_mode = mr.cells
  if len(results) > settings.max_tiles_in_grid and mr.cells == 'tiles':
    grid_cell_mode = 'ids'

  grid_view_data = {
      'grid_limited': ezt.boolean(grid_limited),
      'grid_shown': len(results),
      'grid_x_headings': grid_x_headings,
      'grid_y_headings': grid_y_headings,
      'grid_data': grid_data,
      'grid_axis_choices': grid_axis_choices,
      'grid_cell_mode': grid_cell_mode,
      'results': results,  # Really only useful in if-any.
  }
  return grid_view_data


def PrepareForMakeGridData(
    allowed_results, starred_iid_set, x_attr,
    grid_col_values, y_attr, grid_row_values, users_by_id, all_label_values,
    config, related_issues, hotlist_context_dict=None):
  """Return all data needed for EZT to render the body of the grid view."""

  def IssueViewFactory(issue):
    return template_helpers.EZTItem(
      summary=issue.summary, local_id=issue.local_id, issue_id=issue.issue_id,
      status=issue.status or issue.derived_status, starred=None, data_idx=0,
      project_name=issue.project_name)

  grid_data = MakeGridData(
      allowed_results, x_attr, grid_col_values, y_attr, grid_row_values,
      users_by_id, IssueViewFactory, all_label_values, config, related_issues,
      hotlist_context_dict=hotlist_context_dict)
  issue_dict = {issue.issue_id: issue for issue in allowed_results}
  for grid_row in grid_data:
    for grid_cell in grid_row.cells_in_row:
      for tile in grid_cell.tiles:
        if tile.issue_id in starred_iid_set:
          tile.starred = ezt.boolean(True)
        issue = issue_dict[tile.issue_id]
        tile.issue_url = tracker_helpers.FormatRelativeIssueURL(
            issue.project_name, urls.ISSUE_DETAIL, id=tile.local_id)
        tile.issue_ref = issue.project_name + ':' + str(tile.local_id)

  return grid_data
