# 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

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

This file exports classes TableRow and TableCell that help
represent HTML table rows and cells.  These classes make rendering
HTML tables that list project artifacts much easier to do with EZT.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import collections
import itertools
import logging

from functools import total_ordering

import ezt

from framework import framework_constants
from framework import template_helpers
from framework import timestr
from proto import tracker_pb2
from tracker import tracker_bizobj
from tracker import tracker_constants


def ComputeUnshownColumns(results, shown_columns, config, built_in_cols):
  """Return a list of unshown columns that the user could add.

  Args:
    results: list of search result PBs. Each must have labels.
    shown_columns: list of column names to be used in results table.
    config: harmonized config for the issue search, including all
        well known labels and custom fields.
    built_in_cols: list of other column names that are built into the tool.
      E.g., star count, or creation date.

  Returns:
    List of column names to append to the "..." menu.
  """
  unshown_set = set()  # lowercases column names
  unshown_list = []  # original-case column names
  shown_set = {col.lower() for col in shown_columns}
  labels_already_seen = set()  # whole labels, original case

  def _MaybeAddLabel(label_name):
    """Add the key part of the given label if needed."""
    if label_name.lower() in labels_already_seen:
      return
    labels_already_seen.add(label_name.lower())
    if '-' in label_name:
      col, _value = label_name.split('-', 1)
      _MaybeAddCol(col)

  def _MaybeAddCol(col):
    if col.lower() not in shown_set and col.lower() not in unshown_set:
      unshown_list.append(col)
      unshown_set.add(col.lower())

  # The user can always add any of the default columns.
  for col in config.default_col_spec.split():
    _MaybeAddCol(col)

  # The user can always add any of the built-in columns.
  for col in built_in_cols:
    _MaybeAddCol(col)

  # The user can add a column for any well-known labels
  for wkl in config.well_known_labels:
    _MaybeAddLabel(wkl.label)

  phase_names = set(itertools.chain.from_iterable(
      (phase.name.lower() for phase in result.phases) for result in results))
  # The user can add a column for any custom field
  field_ids_alread_seen = set()
  for fd in config.field_defs:
    field_lower = fd.field_name.lower()
    field_ids_alread_seen.add(fd.field_id)
    if fd.is_phase_field:
      for name in phase_names:
        phase_field_col = name + '.' + field_lower
        if (phase_field_col not in shown_set and
            phase_field_col not in unshown_set):
          unshown_list.append(phase_field_col)
          unshown_set.add(phase_field_col)
    elif field_lower not in shown_set and field_lower not in unshown_set:
      unshown_list.append(fd.field_name)
      unshown_set.add(field_lower)

    if fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE:
      approval_lower_approver = (
          field_lower + tracker_constants.APPROVER_COL_SUFFIX)
      if (approval_lower_approver not in shown_set and
          approval_lower_approver not in unshown_set):
        unshown_list.append(
            fd.field_name + tracker_constants.APPROVER_COL_SUFFIX)
        unshown_set.add(approval_lower_approver)

  # The user can add a column for any key-value label or field in the results.
  for r in results:
    for label_name in tracker_bizobj.GetLabels(r):
      _MaybeAddLabel(label_name)
    for field_value in r.field_values:
      if field_value.field_id not in field_ids_alread_seen:
        field_ids_alread_seen.add(field_value.field_id)
        fd = tracker_bizobj.FindFieldDefByID(field_value.field_id, config)
        if fd:  # could be None for a foreign field, which we don't display.
          field_lower = fd.field_name.lower()
          if field_lower not in shown_set and field_lower not in unshown_set:
            unshown_list.append(fd.field_name)
            unshown_set.add(field_lower)

  return sorted(unshown_list)


def ExtractUniqueValues(columns, artifact_list, users_by_id,
                        config, related_issues, hotlist_context_dict=None):
  """Build a nested list of unique values so the user can auto-filter.

  Args:
    columns: a list of lowercase column name strings, which may contain
        combined columns like "priority/pri".
    artifact_list: a list of artifacts in the complete set of search results.
    users_by_id: dict mapping user_ids to UserViews.
    config: ProjectIssueConfig PB for the current project.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    hotlist_context_dict: dict for building a hotlist grid table

  Returns:
    [EZTItem(col1, colname1, [val11, val12,...]), ...]
    A list of EZTItems, each of which has a col_index, column_name,
    and a list of unique values that appear in that column.
  """
  column_values = {col_name: {} for col_name in columns}

  # For each combined column "a/b/c", add entries that point from "a" back
  # to "a/b/c", from "b" back to "a/b/c", and from "c" back to "a/b/c".
  combined_column_parts = collections.defaultdict(list)
  for col in columns:
    if '/' in col:
      for col_part in col.split('/'):
        combined_column_parts[col_part].append(col)

  unique_labels = set()
  for art in artifact_list:
    unique_labels.update(tracker_bizobj.GetLabels(art))

  for label in unique_labels:
    if '-' in label:
      col, val = label.split('-', 1)
      col = col.lower()
      if col in column_values:
        column_values[col][val.lower()] = val
      if col in combined_column_parts:
        for combined_column in combined_column_parts[col]:
          column_values[combined_column][val.lower()] = val
    else:
      if 'summary' in column_values:
        column_values['summary'][label.lower()] = label

  # TODO(jrobbins): Consider refacting some of this to tracker_bizobj
  # or a new builtins.py to reduce duplication.
  if 'reporter' in column_values:
    for art in artifact_list:
      reporter_id = art.reporter_id
      if reporter_id and reporter_id in users_by_id:
        reporter_username = users_by_id[reporter_id].display_name
        column_values['reporter'][reporter_username] = reporter_username

  if 'owner' in column_values:
    for art in artifact_list:
      owner_id = tracker_bizobj.GetOwnerId(art)
      if owner_id and owner_id in users_by_id:
        owner_username = users_by_id[owner_id].display_name
        column_values['owner'][owner_username] = owner_username

  if 'cc' in column_values:
    for art in artifact_list:
      cc_ids = tracker_bizobj.GetCcIds(art)
      for cc_id in cc_ids:
        if cc_id and cc_id in users_by_id:
          cc_username = users_by_id[cc_id].display_name
          column_values['cc'][cc_username] = cc_username

  if 'component' in column_values:
    for art in artifact_list:
      all_comp_ids = list(art.component_ids) + list(art.derived_component_ids)
      for component_id in all_comp_ids:
        cd = tracker_bizobj.FindComponentDefByID(component_id, config)
        if cd:
          column_values['component'][cd.path] = cd.path

  if 'stars' in column_values:
    for art in artifact_list:
      star_count = art.star_count
      column_values['stars'][star_count] = star_count

  if 'status' in column_values:
    for art in artifact_list:
      status = tracker_bizobj.GetStatus(art)
      if status:
        column_values['status'][status.lower()] = status

  if 'project' in column_values:
    for art in artifact_list:
      project_name = art.project_name
      column_values['project'][project_name] = project_name

  if 'mergedinto' in column_values:
    for art in artifact_list:
      if art.merged_into and art.merged_into != 0:
        merged_issue = related_issues[art.merged_into]
        merged_issue_ref = tracker_bizobj.FormatIssueRef((
            merged_issue.project_name, merged_issue.local_id))
        column_values['mergedinto'][merged_issue_ref] = merged_issue_ref

  if 'blocked' in column_values:
    for art in artifact_list:
      if art.blocked_on_iids:
        column_values['blocked']['is_blocked'] = 'Yes'
      else:
        column_values['blocked']['is_not_blocked'] = 'No'

  if 'blockedon' in column_values:
    for art in artifact_list:
      if art.blocked_on_iids:
        for blocked_on_iid in art.blocked_on_iids:
          blocked_on_issue = related_issues[blocked_on_iid]
          blocked_on_ref = tracker_bizobj.FormatIssueRef((
              blocked_on_issue.project_name, blocked_on_issue.local_id))
          column_values['blockedon'][blocked_on_ref] = blocked_on_ref

  if 'blocking' in column_values:
    for art in artifact_list:
      if art.blocking_iids:
        for blocking_iid in art.blocking_iids:
          blocking_issue = related_issues[blocking_iid]
          blocking_ref = tracker_bizobj.FormatIssueRef((
              blocking_issue.project_name, blocking_issue.local_id))
          column_values['blocking'][blocking_ref] = blocking_ref

  if 'added' in column_values:
    for art in artifact_list:
      if hotlist_context_dict and hotlist_context_dict[art.issue_id]:
        issue_dict = hotlist_context_dict[art.issue_id]
        date_added = issue_dict['date_added']
        column_values['added'][date_added] = date_added

  if 'adder' in column_values:
    for art in artifact_list:
      if hotlist_context_dict and hotlist_context_dict[art.issue_id]:
        issue_dict = hotlist_context_dict[art.issue_id]
        adder_id = issue_dict['adder_id']
        adder = users_by_id[adder_id].display_name
        column_values['adder'][adder] = adder

  if 'note' in column_values:
    for art in artifact_list:
      if hotlist_context_dict and hotlist_context_dict[art.issue_id]:
        issue_dict = hotlist_context_dict[art.issue_id]
        note = issue_dict['note']
        if issue_dict['note']:
          column_values['note'][note] = note

  if 'attachments' in column_values:
    for art in artifact_list:
      attachment_count = art.attachment_count
      column_values['attachments'][attachment_count] = attachment_count

  # Add all custom field values if the custom field name is a shown column.
  field_id_to_col = {}
  for art in artifact_list:
    for fv in art.field_values:
      field_col, field_type = field_id_to_col.get(fv.field_id, (None, None))
      if field_col == 'NOT_SHOWN':
        continue
      if field_col is None:
        fd = tracker_bizobj.FindFieldDefByID(fv.field_id, config)
        if not fd:
          field_id_to_col[fv.field_id] = 'NOT_SHOWN', None
          continue
        field_col = fd.field_name.lower()
        field_type = fd.field_type
        if field_col not in column_values:
          field_id_to_col[fv.field_id] = 'NOT_SHOWN', None
          continue
        field_id_to_col[fv.field_id] = field_col, field_type

      if field_type == tracker_pb2.FieldTypes.ENUM_TYPE:
        continue  # Already handled by label parsing
      elif field_type == tracker_pb2.FieldTypes.INT_TYPE:
        val = fv.int_value
      elif field_type == tracker_pb2.FieldTypes.STR_TYPE:
        val = fv.str_value
      elif field_type == tracker_pb2.FieldTypes.USER_TYPE:
        user = users_by_id.get(fv.user_id)
        val = user.email if user else framework_constants.NO_USER_NAME
      elif field_type == tracker_pb2.FieldTypes.DATE_TYPE:
        val = fv.int_value  # TODO(jrobbins): convert to date
      elif field_type == tracker_pb2.FieldTypes.BOOL_TYPE:
        val = 'Yes' if fv.int_value else 'No'

      column_values[field_col][val] = val

  # TODO(jrobbins): make the capitalization of well-known unique label and
  # status values match the way it is written in the issue config.

  # Return EZTItems for each column in left-to-right display order.
  result = []
  for i, col_name in enumerate(columns):
    # TODO(jrobbins): sort each set of column values top-to-bottom, by the
    # order specified in the project artifact config. For now, just sort
    # lexicographically to make expected output defined.
    sorted_col_values = sorted(column_values[col_name].values())
    result.append(template_helpers.EZTItem(
        col_index=i, column_name=col_name, filter_values=sorted_col_values))

  return result


def MakeTableData(
    visible_results, starred_items, lower_columns, lower_group_by,
    users_by_id, cell_factories, id_accessor, related_issues,
    viewable_iids_set, config, context_for_all_issues=None):
  """Return a list of list row objects for display by EZT.

  Args:
    visible_results: list of artifacts to display on one pagination page.
    starred_items: list of IDs/names of items in the current project
        that the signed in user has starred.
    lower_columns: list of column names to display, all lowercase.  These can
        be combined column names, e.g., 'priority/pri'.
    lower_group_by: list of column names that define row groups, all lowercase.
    users_by_id: dict mapping user IDs to UserViews.
    cell_factories: dict of functions that each create TableCell objects.
    id_accessor: function that maps from an artifact to the ID/name that might
        be in the starred items list.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    viewable_iids_set: set of issue ids that can be viewed by the user.
    config: ProjectIssueConfig PB for the current project.
    context_for_all_issues: A dictionary of dictionaries containing values
        passed in to cell factory functions to create TableCells. Dictionary
        form: {issue_id: {'rank': issue_rank, 'issue_info': info_value, ..},
        issue_id: {'rank': issue_rank}, ..}

  Returns:
    A list of TableRow objects, one for each visible result.
  """
  table_data = []

  group_cell_factories = [
      ChooseCellFactory(group.strip('-'), cell_factories, config)
      for group in lower_group_by]

  # Make a list of cell factories, one for each column.
  factories_to_use = [
      ChooseCellFactory(col, cell_factories, config) for col in lower_columns]

  current_group = None
  for idx, art in enumerate(visible_results):
    row = MakeRowData(
        art, lower_columns, users_by_id, factories_to_use, related_issues,
        viewable_iids_set, config, context_for_all_issues)
    row.starred = ezt.boolean(id_accessor(art) in starred_items)
    row.idx = idx  # EZT does not have loop counters, so add idx.
    table_data.append(row)
    row.group = None

    # Also include group information for the first row in each group.
    # TODO(jrobbins): This seems like more overhead than we need for the
    # common case where no new group heading row is to be inserted.
    group = MakeRowData(
        art, [group_name.strip('-') for group_name in lower_group_by],
        users_by_id, group_cell_factories, related_issues, viewable_iids_set,
        config, context_for_all_issues)
    for cell, group_name in zip(group.cells, lower_group_by):
      cell.group_name = group_name
    if group == current_group:
      current_group.rows_in_group += 1
    else:
      row.group = group
      current_group = group
      current_group.rows_in_group = 1

  return table_data


def MakeRowData(
    art, columns, users_by_id, cell_factory_list, related_issues,
    viewable_iids_set, config, context_for_all_issues):
  """Make a TableRow for use by EZT when rendering HTML table of results.

  Args:
    art: a project artifact PB
    columns: list of lower-case column names
    users_by_id: dictionary {user_id: UserView} with each UserView having
        a "display_name" member.
    cell_factory_list: list of functions that each create TableCell
        objects for a given column.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    viewable_iids_set: set of issue ids that can be viewed by the user.
    config: ProjectIssueConfig PB for the current project.
    context_for_all_issues: A dictionary of dictionaries containing values
        passed in to cell factory functions to create TableCells. Dictionary
        form: {issue_id: {'rank': issue_rank, 'issue_info': info_value, ..},
        issue_id: {'rank': issue_rank}, ..}

  Returns:
    A TableRow object for use by EZT to render a table of results.
  """
  if context_for_all_issues is None:
    context_for_all_issues = {}
  ordered_row_data = []
  non_col_labels = []
  label_values = collections.defaultdict(list)

  flattened_columns = set()
  for col in columns:
    if '/' in col:
      flattened_columns.update(col.split('/'))
    else:
      flattened_columns.add(col)

  # Group all "Key-Value" labels by key, and separate the "OneWord" labels.
  _AccumulateLabelValues(
      art.labels, flattened_columns, label_values, non_col_labels)

  _AccumulateLabelValues(
      art.derived_labels, flattened_columns, label_values,
      non_col_labels, is_derived=True)

  # Build up a list of TableCell objects for this row.
  for i, col in enumerate(columns):
    factory = cell_factory_list[i]
    kw = {
        'col': col,
        'users_by_id': users_by_id,
        'non_col_labels': non_col_labels,
        'label_values': label_values,
        'related_issues': related_issues,
        'viewable_iids_set': viewable_iids_set,
        'config': config,
        }
    kw.update(context_for_all_issues.get(art.issue_id, {}))
    new_cell = factory(art, **kw)
    new_cell.col_index = i
    ordered_row_data.append(new_cell)

  return TableRow(ordered_row_data)


def _AccumulateLabelValues(
    labels, columns, label_values, non_col_labels, is_derived=False):
  """Parse OneWord and Key-Value labels for display in a list page.

  Args:
    labels: a list of label strings.
    columns: a list of column names.
    label_values: mutable dictionary {key: [value, ...]} of label values
        seen so far.
    non_col_labels: mutable list of OneWord labels seen so far.
    is_derived: true if these labels were derived via rules.

  Returns:
    Nothing.  But, the given label_values dictionary will grow to hold
    the values of the key-value labels passed in, and the non_col_labels
    list will grow to hold the OneWord labels passed in.  These are shown
    in label columns, and in the summary column, respectively
  """
  for label_name in labels:
    if '-' in label_name:
      parts = label_name.split('-')
      for pivot in range(1, len(parts)):
        column_name = '-'.join(parts[:pivot])
        value = '-'.join(parts[pivot:])
        column_name = column_name.lower()
        if column_name in columns:
          label_values[column_name].append((value, is_derived))
    else:
      non_col_labels.append((label_name, is_derived))


@total_ordering
class TableRow(object):
  """A tiny auxiliary class to represent a row in an HTML table."""

  def __init__(self, cells):
    """Initialize the table row with the given data."""
    self.cells = cells
    # Used by MakeTableData for layout.
    self.idx = None
    self.group = None
    self.rows_in_group = None
    self.starred = None

  def __eq__(self, other):
    """A row is == if each cell is == to the cells in the other row."""
    return other and self.cells == other.cells

  def __ne__(self, other):
    return not other and self.cells != other.cells

  def __lt__(self, other):
    return other and self.cells < other.cells

  def DebugString(self):
    """Return a string that is useful for on-page debugging."""
    return 'TR(%s)' % self.cells


# TODO(jrobbins): also add unsortable... or change this to a list of operations
# that can be done.
CELL_TYPE_ID = 'ID'
CELL_TYPE_SUMMARY = 'summary'
CELL_TYPE_ATTR = 'attr'
CELL_TYPE_UNFILTERABLE = 'unfilterable'
CELL_TYPE_NOTE = 'note'
CELL_TYPE_PROJECT = 'project'
CELL_TYPE_URL = 'url'
CELL_TYPE_ISSUES = 'issues'


@total_ordering
class TableCell(object):
  """Helper class to represent a table cell when rendering using EZT."""

  # Should instances of this class be rendered with whitespace:nowrap?
  # Subclasses can override this constant.
  NOWRAP = ezt.boolean(True)

  def __init__(self, cell_type, explicit_values,
               derived_values=None, non_column_labels=None, align='',
               sort_values=True):
    """Store all the given data for later access by EZT."""
    self.type = cell_type
    self.align = align
    self.col_index = 0  # Is set afterward
    self.values = []
    if non_column_labels:
      self.non_column_labels = [
          template_helpers.EZTItem(value=v, is_derived=ezt.boolean(d))
          for v, d in non_column_labels]
    else:
      self.non_column_labels = []

    for v in (sorted(explicit_values) if sort_values else explicit_values):
      self.values.append(CellItem(v))

    if derived_values:
      for v in (sorted(derived_values) if sort_values else derived_values):
        self.values.append(CellItem(v, is_derived=True))

  def __eq__(self, other):
    """A row is == if each cell is == to the cells in the other row."""
    return other and self.values == other.values

  def __ne__(self, other):
    return not other and self.values != other.values

  def __lt__(self, other):
    return other and self.values < other.values

  def DebugString(self):
    return 'TC(%r, %r, %r)' % (
        self.type,
        [v.DebugString() for v in self.values],
        self.non_column_labels)


def CompositeFactoryTableCell(factory_col_list_arg):
  """Cell factory that combines multiple cells in a combined column."""

  class FactoryClass(TableCell):
    factory_col_list = factory_col_list_arg

    def __init__(self, art, **kw):
      TableCell.__init__(self, CELL_TYPE_UNFILTERABLE, [])

      for sub_factory, sub_col in self.factory_col_list:
        kw['col'] = sub_col
        sub_cell = sub_factory(art, **kw)
        self.non_column_labels.extend(sub_cell.non_column_labels)
        self.values.extend(sub_cell.values)
  return FactoryClass


def CompositeColTableCell(columns_to_combine, cell_factories, config):
  """Cell factory that combines multiple cells in a combined column."""
  factory_col_list = []
  for sub_col in columns_to_combine:
    sub_factory = ChooseCellFactory(sub_col, cell_factories, config)
    factory_col_list.append((sub_factory, sub_col))
  return CompositeFactoryTableCell(factory_col_list)


@total_ordering
class CellItem(object):
  """Simple class to display one part of a table cell's value, with style."""

  def __init__(self, item, is_derived=False):
    self.item = item
    self.is_derived = ezt.boolean(is_derived)

  def __eq__(self, other):
    """A row is == if each cell is == to the item in the other row."""
    return other and self.item == other.item

  def __ne__(self, other):
    return not other and self.item != other.item

  def __lt__(self, other):
    return other and self.item < other.item

  def DebugString(self):
    if self.is_derived:
      return 'CI(derived: %r)' % self.item
    else:
      return 'CI(%r)' % self.item


class TableCellKeyLabels(TableCell):
  """TableCell subclass specifically for showing user-defined label values."""

  def __init__(self, _art, col=None, label_values=None,  **_kw):
    label_value_pairs = label_values.get(col, [])
    explicit_values = [value for value, is_derived in label_value_pairs
                       if not is_derived]
    derived_values = [value for value, is_derived in label_value_pairs
                      if is_derived]
    TableCell.__init__(self, CELL_TYPE_ATTR, explicit_values,
                       derived_values=derived_values)


class TableCellProject(TableCell):
  """TableCell subclass for showing an artifact's project name."""

  def __init__(self, art, **_kw):
    TableCell.__init__(
        self, CELL_TYPE_PROJECT, [art.project_name])


class TableCellStars(TableCell):
  """TableCell subclass for showing an artifact's star count."""

  def __init__(self, art, **_kw):
    TableCell.__init__(
        self, CELL_TYPE_ATTR, [art.star_count], align='right')


class TableCellSummary(TableCell):
  """TableCell subclass for showing an artifact's summary."""

  def __init__(self, art, non_col_labels=None, **_kw):
    TableCell.__init__(
        self, CELL_TYPE_SUMMARY, [art.summary],
        non_column_labels=non_col_labels)


class TableCellDate(TableCell):
  """TableCell subclass for showing any kind of date timestamp."""

  # Make instances of this class render with whitespace:nowrap.
  NOWRAP = ezt.boolean(True)

  def __init__(self, timestamp, days_only=False):
    values = []
    if timestamp:
      date_str = timestr.FormatRelativeDate(timestamp, days_only=days_only)
      if not date_str:
        date_str = timestr.FormatAbsoluteDate(timestamp)
      values = [date_str]

    TableCell.__init__(self, CELL_TYPE_UNFILTERABLE, values)


class TableCellCustom(TableCell):
  """Abstract TableCell subclass specifically for showing custom fields."""

  def __init__(self, art, col=None, users_by_id=None, config=None, **_kw):
    explicit_values = []
    derived_values = []
    cell_type = CELL_TYPE_ATTR
    phase_names_by_id = {
        phase.phase_id: phase.name.lower() for phase in art.phases}
    phase_name = None
    # Check if col represents a phase field value in the form <phase>.<field>
    if '.' in col:
      phase_name, col = col.split('.', 1)
    for fv in art.field_values:
      # TODO(jrobbins): for cross-project search this could be a list.
      fd = tracker_bizobj.FindFieldDefByID(fv.field_id, config)
      if not fd:
        # TODO(jrobbins): This can happen if an issue with a custom
        # field value is moved to a different project.
        logging.warn('Issue ID %r has undefined field value %r',
                     art.issue_id, fv)
      elif fd.field_name.lower() == col and (
          phase_names_by_id.get(fv.phase_id) == phase_name):
        if fd.field_type == tracker_pb2.FieldTypes.URL_TYPE:
          cell_type = CELL_TYPE_URL
        if fd.field_type == tracker_pb2.FieldTypes.STR_TYPE:
          self.NOWRAP = ezt.boolean(False)
        val = tracker_bizobj.GetFieldValue(fv, users_by_id)
        if fv.derived:
          derived_values.append(val)
        else:
          explicit_values.append(val)

    TableCell.__init__(self, cell_type, explicit_values,
                       derived_values=derived_values)

  def ExtractValue(self, fv, _users_by_id):
    return 'field-id-%d-not-implemented-yet' % fv.field_id

class TableCellApprovalStatus(TableCell):
  """Abstract TableCell subclass specifically for showing approval fields."""

  def __init__(self, art, col=None, config=None, **_kw):
    explicit_values = []
    for av in art.approval_values:
      fd = tracker_bizobj.FindFieldDef(col, config)
      ad = tracker_bizobj.FindApprovalDef(col, config)
      if not (ad and fd):
        logging.warn('Issue ID %r has undefined field value %r',
                     art.issue_id, av)
      elif av.approval_id == fd.field_id:
        explicit_values.append(av.status.name)
        break

    TableCell.__init__(self, CELL_TYPE_ATTR, explicit_values)


class TableCellApprovalApprover(TableCell):
  """TableCell subclass specifically for showing approval approvers."""

  def __init__(self, art, col=None, config=None, users_by_id=None, **_kw):
    explicit_values = []
    approval_name = col[:-len(tracker_constants.APPROVER_COL_SUFFIX)]
    for av in art.approval_values:
      fd = tracker_bizobj.FindFieldDef(approval_name, config)
      ad = tracker_bizobj.FindApprovalDef(approval_name, config)
      if not (ad and fd):
        logging.warn('Issue ID %r has undefined field value %r',
                     art.issue_id, av)
      elif av.approval_id == fd.field_id:
        explicit_values = [users_by_id.get(approver_id).display_name
                           for approver_id in av.approver_ids
                           if users_by_id.get(approver_id)]
        break

    TableCell.__init__(self, CELL_TYPE_ATTR, explicit_values)

def ChooseCellFactory(col, cell_factories, config):
  """Return the CellFactory to use for the given column."""
  if col in cell_factories:
    return cell_factories[col]

  if '/' in col:
    return CompositeColTableCell(col.split('/'), cell_factories, config)

  is_approver_col = False
  possible_field_name = col
  if col.endswith(tracker_constants.APPROVER_COL_SUFFIX):
    possible_field_name = col[:-len(tracker_constants.APPROVER_COL_SUFFIX)]
    is_approver_col = True
  # Check if col represents a phase field value in the form <phase>.<field>
  elif '.' in possible_field_name:
    possible_field_name = possible_field_name.split('.')[-1]

  fd = tracker_bizobj.FindFieldDef(possible_field_name, config)
  if fd:
    # We cannot assume that non-enum_type field defs do not share their
    # names with label prefixes. So we need to group them with
    # TableCellKeyLabels to make sure we catch appropriate labels values.
    if fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE:
      if is_approver_col:
        # Combined cell for 'FieldName-approver' to hold approvers
        # belonging to FieldName and values belonging to labels with
        # 'FieldName-approver' as the key.
        return CompositeFactoryTableCell(
          [(TableCellApprovalApprover, col), (TableCellKeyLabels, col)])
      return CompositeFactoryTableCell(
          [(TableCellApprovalStatus, col), (TableCellKeyLabels, col)])
    elif fd.field_type != tracker_pb2.FieldTypes.ENUM_TYPE:
      return CompositeFactoryTableCell(
          [(TableCellCustom, col), (TableCellKeyLabels, col)])

  return TableCellKeyLabels
