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

"""View objects to help display tracker business objects in templates."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import collections
import logging
import re
import time
from six.moves import urllib

from google.appengine.api import app_identity
import ezt

from features import federated
from framework import exceptions
from framework import filecontent
from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
from framework import framework_views
from framework import gcs_helpers
from framework import permissions
from framework import template_helpers
from framework import timestr
from framework import urls
from mrproto import tracker_pb2
from tracker import attachment_helpers
from tracker import tracker_bizobj
from tracker import tracker_constants
from tracker import tracker_helpers


class IssueView(template_helpers.PBProxy):
  """Wrapper class that makes it easier to display an Issue via EZT."""

  def __init__(self, issue, users_by_id, config):
    """Store relevant values for later display by EZT.

    Args:
      issue: An Issue protocol buffer.
      users_by_id: dict {user_id: UserViews} for all users mentioned in issue.
      config: ProjectIssueConfig for this issue.
    """
    super(IssueView, self).__init__(issue)

    # The users involved in this issue must be present in users_by_id if
    # this IssueView is to be used on the issue detail or peek pages. But,
    # they can be absent from users_by_id if the IssueView is used as a
    # tile in the grid view.
    self.owner = users_by_id.get(issue.owner_id)
    self.derived_owner = users_by_id.get(issue.derived_owner_id)
    self.cc = [users_by_id.get(cc_id) for cc_id in issue.cc_ids
               if cc_id]
    self.derived_cc = [users_by_id.get(cc_id)
                       for cc_id in issue.derived_cc_ids
                       if cc_id]
    self.status = framework_views.StatusView(issue.status, config)
    self.derived_status = framework_views.StatusView(
        issue.derived_status, config)
    # If we don't have a config available, we don't need to access is_open, so
    # let it be True.
    self.is_open = ezt.boolean(
        not config or
        tracker_helpers.MeansOpenInProject(
            tracker_bizobj.GetStatus(issue), config))

    self.components = sorted(
        [ComponentValueView(component_id, config, False)
         for component_id in issue.component_ids
         if tracker_bizobj.FindComponentDefByID(component_id, config)] +
        [ComponentValueView(component_id, config, True)
         for component_id in issue.derived_component_ids
         if tracker_bizobj.FindComponentDefByID(component_id, config)],
        key=lambda cvv: cvv.path)

    self.fields = MakeAllFieldValueViews(
        config, issue.labels, issue.derived_labels, issue.field_values,
        users_by_id)

    labels, derived_labels = tracker_bizobj.ExplicitAndDerivedNonMaskedLabels(
        issue.labels, issue.derived_labels, config)
    self.labels = [
        framework_views.LabelView(label, config)
        for label in labels]
    self.derived_labels = [
        framework_views.LabelView(label, config)
        for label in derived_labels]
    self.restrictions = _RestrictionsView(issue)

    # TODO(jrobbins): sort by order of labels in project config

    self.short_summary = issue.summary[:tracker_constants.SHORT_SUMMARY_LENGTH]

    if issue.closed_timestamp:
      self.closed = timestr.FormatAbsoluteDate(issue.closed_timestamp)
    else:
      self.closed = ''

    self.blocked_on = []
    self.has_dangling = ezt.boolean(self.dangling_blocked_on_refs)
    self.blocking = []

    self.detail_relative_url = tracker_helpers.FormatRelativeIssueURL(
        issue.project_name, urls.ISSUE_DETAIL, id=issue.local_id)
    self.crbug_url = tracker_helpers.FormatCrBugURL(
        issue.project_name, issue.local_id)


class _RestrictionsView(object):
  """An EZT object for the restrictions associated with an issue."""

  # Restrict label fragments that correspond to known permissions.
  _VIEW = permissions.VIEW.lower()
  _EDIT = permissions.EDIT_ISSUE.lower()
  _ADD_COMMENT = permissions.ADD_ISSUE_COMMENT.lower()
  _KNOWN_ACTION_KINDS = {_VIEW, _EDIT, _ADD_COMMENT}

  def __init__(self, issue):
    # List of restrictions that don't map to a known action kind.
    self.other = []

    restrictions_by_action = collections.defaultdict(list)
    # We can't use GetRestrictions here, as we prefer to preserve
    # the case of the label when showing restrictions in the UI.
    for label in tracker_bizobj.GetLabels(issue):
      if permissions.IsRestrictLabel(label):
        _kw, action_kind, needed_perm = label.split('-', 2)
        action_kind = action_kind.lower()
        if action_kind in self._KNOWN_ACTION_KINDS:
          restrictions_by_action[action_kind].append(needed_perm)
        else:
          self.other.append(label)

    self.view = ' and '.join(restrictions_by_action[self._VIEW])
    self.add_comment = ' and '.join(restrictions_by_action[self._ADD_COMMENT])
    self.edit = ' and '.join(restrictions_by_action[self._EDIT])

    self.has_restrictions = ezt.boolean(
        self.view or self.add_comment or self.edit or self.other)


class IssueCommentView(template_helpers.PBProxy):
  """Wrapper class that makes it easier to display an IssueComment via EZT."""

  def __init__(
      self, project_name, comment_pb, users_by_id, autolink,
      all_referenced_artifacts, mr, issue, effective_ids=None):
    """Get IssueComment PB and make its fields available as attrs.

    Args:
      project_name: Name of the project this issue belongs to.
      comment_pb: Comment protocol buffer.
      users_by_id: dict mapping user_ids to UserViews, including
          the user that entered the comment, and any changed participants.
      autolink: utility object for automatically linking to other
        issues, git revisions, etc.
      all_referenced_artifacts: opaque object with details of referenced
        artifacts that is needed by autolink.
      mr: common information parsed from the HTTP request.
      issue: Issue PB for the issue that this comment is part of.
      effective_ids: optional set of int user IDs for the comment author.
    """
    super(IssueCommentView, self).__init__(comment_pb)

    self.id = comment_pb.id
    self.creator = users_by_id[comment_pb.user_id]

    # TODO(jrobbins): this should be based on the issue project, not the
    # request project for non-project views and cross-project.
    if mr.project:
      self.creator_role = framework_helpers.GetRoleName(
          effective_ids or {self.creator.user_id}, mr.project)
    else:
      self.creator_role = None

    time_tuple = time.localtime(comment_pb.timestamp)
    self.date_string = timestr.FormatAbsoluteDate(
        comment_pb.timestamp, old_format=timestr.MONTH_DAY_YEAR_FMT)
    self.date_relative = timestr.FormatRelativeDate(comment_pb.timestamp)
    self.date_tooltip = time.asctime(time_tuple)
    self.date_yyyymmdd = timestr.FormatAbsoluteDate(
        comment_pb.timestamp, recent_format=timestr.MONTH_DAY_YEAR_FMT,
        old_format=timestr.MONTH_DAY_YEAR_FMT)
    self.text_runs = _ParseTextRuns(comment_pb.content)
    if autolink and not comment_pb.deleted_by:
      self.text_runs = autolink.MarkupAutolinks(
          mr, self.text_runs, all_referenced_artifacts)

    self.attachments = [AttachmentView(attachment, project_name)
                        for attachment in comment_pb.attachments]
    self.amendments = sorted([
        AmendmentView(amendment, users_by_id, mr.project_name)
        for amendment in comment_pb.amendments],
        key=lambda amendment: amendment.field_name.lower())
    # Treat comments from banned users as being deleted.
    self.is_deleted = (comment_pb.deleted_by or
                       (self.creator and self.creator.banned))
    self.can_delete = False

    # TODO(jrobbins): pass through config to get granted permissions.
    perms = permissions.UpdateIssuePermissions(
        mr.perms, mr.project, issue, mr.auth.effective_ids)
    if mr.auth.user_id and mr.project:
      self.can_delete = permissions.CanDeleteComment(
          comment_pb, self.creator, mr.auth.user_id, perms)

    self.visible = permissions.CanViewComment(
        comment_pb, self.creator, mr.auth.user_id, perms)


_TEMPLATE_TEXT_RE = re.compile('^(<b>[^<]+</b>)', re.MULTILINE)


def _ParseTextRuns(content):
  """Convert the user's comment to a list of TextRun objects."""
  chunks = _TEMPLATE_TEXT_RE.split(content.strip())
  runs = [_ChunkToRun(chunk) for chunk in chunks]
  return runs


def _ChunkToRun(chunk):
  """Convert a substring of the user's comment to a TextRun object."""
  if chunk.startswith('<b>') and chunk.endswith('</b>'):
    return template_helpers.TextRun(chunk[3:-4], tag='b')
  else:
    return template_helpers.TextRun(chunk)


class LogoView(template_helpers.PBProxy):
  """Wrapper class to make it easier to display project logos via EZT."""

  def __init__(self, project_pb):
    super(LogoView, self).__init__(None)
    if (not project_pb or
        not project_pb.logo_gcs_id or
        not project_pb.logo_file_name):
      self.thumbnail_url = ''
      self.viewurl = ''
      return

    bucket_name = app_identity.get_default_gcs_bucket_name()
    gcs_object = project_pb.logo_gcs_id
    self.filename = project_pb.logo_file_name
    self.mimetype = filecontent.GuessContentTypeFromFilename(self.filename)

    self.thumbnail_url = gcs_helpers.SignUrl(bucket_name,
        gcs_object + '-thumbnail')
    self.viewurl = (
        gcs_helpers.SignUrl(bucket_name, gcs_object) + '&' +
        urllib.parse.urlencode(
            {
                'response-content-displacement':
                    ('attachment; filename=%s' % self.filename)
            }))


class AttachmentView(template_helpers.PBProxy):
  """Wrapper class to make it easier to display issue attachments via EZT."""

  def __init__(self, attach_pb, project_name):
    """Get IssueAttachmentContent PB and make its fields available as attrs.

    Args:
      attach_pb: Attachment part of IssueComment protocol buffer.
      project_name: string Name of the current project.
    """
    super(AttachmentView, self).__init__(attach_pb)
    self.filesizestr = template_helpers.BytesKbOrMb(attach_pb.filesize)
    self.downloadurl = attachment_helpers.GetDownloadURL(
        attach_pb.attachment_id)
    self.url = attachment_helpers.GetViewURL(
        attach_pb, self.downloadurl, project_name)
    self.thumbnail_url = attachment_helpers.GetThumbnailURL(
        attach_pb, self.downloadurl)
    self.video_url = attachment_helpers.GetVideoURL(
        attach_pb, self.downloadurl)

    self.iconurl = '/images/paperclip.png'


class AmendmentView(object):
  """Wrapper class that makes it easier to display an Amendment via EZT."""

  def __init__(self, amendment, users_by_id, project_name):
    """Get the info from the PB and put it into easily accessible attrs.

    Args:
      amendment: Amendment part of an IssueComment protocol buffer.
      users_by_id: dict mapping user_ids to UserViews.
      project_name: Name of the project the issue/comment/amendment is in.
    """
    # TODO(jrobbins): take field-level restrictions into account.
    # Including the case where user is not allowed to see any amendments.
    self.field_name = tracker_bizobj.GetAmendmentFieldName(amendment)
    self.newvalue = tracker_bizobj.AmendmentString(amendment, users_by_id)
    self.values = tracker_bizobj.AmendmentLinks(
        amendment, users_by_id, project_name)


class ComponentDefView(template_helpers.PBProxy):
  """Wrapper class to make it easier to display component definitions."""

  def __init__(self, cnxn, services, component_def, users_by_id):
    super(ComponentDefView, self).__init__(component_def)

    c_path = component_def.path
    if '>' in c_path:
      self.parent_path = c_path[:c_path.rindex('>')]
      self.leaf_name = c_path[c_path.rindex('>') + 1:]
    else:
      self.parent_path = ''
      self.leaf_name = c_path

    self.docstring_short = template_helpers.FitUnsafeText(
        component_def.docstring, 200)

    self.admins = [users_by_id.get(admin_id)
                   for admin_id in component_def.admin_ids]
    self.cc = [users_by_id.get(cc_id) for cc_id in component_def.cc_ids]
    self.labels = [
        services.config.LookupLabel(cnxn, component_def.project_id, label_id)
        for label_id in component_def.label_ids]
    self.classes = 'all '
    if self.parent_path == '':
      self.classes += 'toplevel '
    self.classes += 'deprecated ' if component_def.deprecated else 'active '


class ComponentValueView(object):
  """Wrapper class that makes it easier to display a component value."""

  def __init__(self, component_id, config, derived):
    """Make the component name and docstring available as attrs.

    Args:
      component_id: int component_id to look up in the config
      config: ProjectIssueConfig PB for the issue's project.
      derived: True if this component was derived.
    """
    cd = tracker_bizobj.FindComponentDefByID(component_id, config)
    self.path = cd.path
    self.docstring = cd.docstring
    self.docstring_short = template_helpers.FitUnsafeText(cd.docstring, 60)
    self.derived = ezt.boolean(derived)


class FieldValueView(object):
  """Wrapper class that makes it easier to display a custom field value."""

  def __init__(
      self, fd, config, values, derived_values, issue_types, applicable=None,
      phase_name=None):
    """Make several values related to this field available as attrs.

    Args:
      fd: field definition to be displayed (or not, if no value).
      config: ProjectIssueConfig PB for the issue's project.
      values: list of explicit field values.
      derived_values: list of derived field values.
      issue_types: set of lowered string values from issues' "Type-*" labels.
      applicable: optional boolean that overrides the rule that determines
          when a field is applicable.
      phase_name: name of the phase this field value belongs to.
    """
    self.field_def = FieldDefView(fd, config)
    self.field_id = fd.field_id
    self.field_name = fd.field_name
    self.field_docstring = fd.docstring
    self.field_docstring_short = template_helpers.FitUnsafeText(
        fd.docstring, 60)
    self.phase_name = phase_name or ""

    self.values = values
    self.derived_values = derived_values

    self.applicable_type = fd.applicable_type
    if applicable is not None:
      self.applicable = ezt.boolean(applicable)
    else:
      # Note: We don't show approval types, approval sub fields, or
      # phase fields in ezt issue pages.
      if (fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE or
          fd.approval_id or fd.is_phase_field):
        self.applicable = ezt.boolean(False)
      else:
        # A field is applicable to a given issue if it (a) applies to all,
        # issues or (b) already has a value on this issue, or (c) says that
        # it applies to issues with this type (or a prefix of it).
        applicable_type_lower = self.applicable_type.lower()
        self.applicable = ezt.boolean(
            not self.applicable_type or values or
            any(type_label.startswith(applicable_type_lower)
                for type_label in issue_types))
      # TODO(jrobbins): also evaluate applicable_predicate

    self.display = ezt.boolean(   # or fd.show_empty
        self.values or self.derived_values or
        (self.applicable and not fd.is_niche))

    #FieldValueView does not handle determining if it's editable
    #by the logged-in user. This can be determined by using
    #permission.CanEditValueForFieldDef.
    self.is_editable = ezt.boolean(True)


def _PrecomputeInfoForValueViews(labels, derived_labels, field_values, config,
                                 phases):
  """Organize issue values into datastructures used to make FieldValueViews."""
  field_values_by_id = collections.defaultdict(list)
  for fv in field_values:
    field_values_by_id[fv.field_id].append(fv)
  lower_enum_field_names = [
      fd.field_name.lower() for fd in config.field_defs
      if fd.field_type == tracker_pb2.FieldTypes.ENUM_TYPE]
  labels_by_prefix = tracker_bizobj.LabelsByPrefix(
      labels, lower_enum_field_names)
  der_labels_by_prefix = tracker_bizobj.LabelsByPrefix(
      derived_labels, lower_enum_field_names)
  label_docs = {wkl.label.lower(): wkl.label_docstring
                for wkl in config.well_known_labels}
  phases_by_name = collections.defaultdict(list)
  # group issue phases by name
  for phase in phases:
    phases_by_name[phase.name.lower()].append(phase)
  return (labels_by_prefix, der_labels_by_prefix, field_values_by_id,
          label_docs, phases_by_name)


def MakeAllFieldValueViews(
    config, labels, derived_labels, field_values, users_by_id,
    parent_approval_ids=None, phases=None):
  """Return a list of FieldValues, each containing values from the issue.
     A phase field value view will be created for each unique phase name found
     in the given list a phases. Phase field value views will not be created
     if the phases list is empty.
  """
  parent_approval_ids = parent_approval_ids or []
  precomp_view_info = _PrecomputeInfoForValueViews(
      labels, derived_labels, field_values, config, phases or [])
  def GetApplicable(fd):
    if fd.approval_id and fd.approval_id in parent_approval_ids:
      return True
    return None
  field_value_views = [
      _MakeFieldValueView(fd, config, precomp_view_info, users_by_id,
                          applicable=GetApplicable(fd))
      # TODO(jrobbins): field-level view restrictions, display options
      for fd in config.field_defs
      if not fd.is_deleted and not fd.is_phase_field]

  # Make a phase field's view for each unique phase_name found in phases.
  (_, _, _, _, phases_by_name) = precomp_view_info
  for phase_name in sorted(phases_by_name.keys()):
    field_value_views.extend([
        _MakeFieldValueView(
            fd, config, precomp_view_info, users_by_id, phase_name=phase_name)
        for fd in config.field_defs if fd.is_phase_field])

  field_value_views = sorted(
      field_value_views, key=lambda f: (f.applicable_type, f.field_name))
  return field_value_views


def _MakeFieldValueView(
    fd, config, precomp_view_info, users_by_id, applicable=None,
    phase_name=None):
  """Return a FieldValueView with all values from the issue for that field."""
  (labels_by_prefix, der_labels_by_prefix, field_values_by_id,
   label_docs, phases_by_name) = precomp_view_info

  field_name_lower = fd.field_name.lower()
  values = []
  derived_values = []

  if fd.field_type == tracker_pb2.FieldTypes.ENUM_TYPE:
    values = _ConvertLabelsToFieldValues(
        labels_by_prefix.get(field_name_lower, []),
        field_name_lower, label_docs)
    derived_values = _ConvertLabelsToFieldValues(
        der_labels_by_prefix.get(field_name_lower, []),
        field_name_lower, label_docs)
  else:
    # Phases with the same name may have different phase_ids. Phases
    # are defined during template creation and updating a template structure
    # may result in new phase rows to be created while existing issues
    # are referencing older phase rows.
    phase_ids_for_phase_name = [
        phase.phase_id for phase in phases_by_name.get(phase_name, [])]
    # If a phase_name is given, we must filter field_values_by_id fvs to those
    # that belong to the given phase. This is not done for labels
    # because monorail does not support phase enum_type field values.
    values = _MakeFieldValueItems(
        [fv for fv in field_values_by_id.get(fd.field_id, [])
         if not fv.derived and
         (not phase_name or (fv.phase_id in phase_ids_for_phase_name))],
        users_by_id)
    derived_values = _MakeFieldValueItems(
        [fv for fv in field_values_by_id.get(fd.field_id, [])
         if fv.derived and
         (not phase_name or (fv.phase_id in phase_ids_for_phase_name))],
        users_by_id)

  issue_types = (labels_by_prefix.get('type', []) +
                 der_labels_by_prefix.get('type', []))
  issue_types_lower = [it.lower() for it in issue_types]

  return FieldValueView(fd, config, values, derived_values, issue_types_lower,
                        applicable=applicable, phase_name=phase_name)


def _MakeFieldValueItems(field_values, users_by_id):
  """Make appropriate int, string, or user values in the given fields."""
  result = []
  for fv in field_values:
    val = tracker_bizobj.GetFieldValue(fv, users_by_id)
    result.append(template_helpers.EZTItem(
        val=val, docstring=val, idx=len(result)))

  return result


def MakeBounceFieldValueViews(
    field_vals, phase_field_vals, config, applicable_fields=None):
  # type: (Sequence[mrproto.tracker_pb2.FieldValue],
  #     Sequence[mrproto.tracker_pb2.FieldValue],
  #     mrproto.tracker_pb2.ProjectIssueConfig
  #     Sequence[mrproto.tracker_pb2.FieldDef]) -> Sequence[FieldValueView]
  """Return a list of field values to display on a validation bounce page."""
  applicable_set = set()
  # Handle required fields
  if applicable_fields:
    for fd in applicable_fields:
      applicable_set.add(fd.field_id)

  field_value_views = []
  for fd in config.field_defs:
    if fd.field_id in field_vals:
      # TODO(jrobbins): also bounce derived values.
      val_items = [
          template_helpers.EZTItem(val=v, docstring='', idx=idx)
          for idx, v in enumerate(field_vals[fd.field_id])]
      field_value_views.append(FieldValueView(
          fd, config, val_items, [], None, applicable=True))
    elif fd.field_id in phase_field_vals:
      vals_by_phase_name = phase_field_vals.get(fd.field_id)
      for phase_name, values in vals_by_phase_name.items():
        val_items = [
            template_helpers.EZTItem(val=v, docstring='', idx=idx)
            for idx, v in enumerate(values)]
        field_value_views.append(FieldValueView(
            fd, config, val_items, [], None, applicable=False,
            phase_name=phase_name))
    elif fd.is_required and fd.field_id in applicable_set:
      # Show required fields that have no value set.
      field_value_views.append(
          FieldValueView(fd, config, [], [], None, applicable=True))

  return field_value_views


def _ConvertLabelsToFieldValues(label_values, field_name_lower, label_docs):
  """Iterate through the given labels and pull out values for the field.

  Args:
    label_values: a list of label strings for the given field.
    field_name_lower: lowercase string name of the custom field.
    label_docs: {lower_label: docstring} for well-known labels in the project.

  Returns:
    A list of EZT items with val and docstring fields.  One item is included
    for each label that matches the given field name.
  """
  values = []
  for idx, lab_val in enumerate(label_values):
    full_label_lower = '%s-%s' % (field_name_lower, lab_val.lower())
    values.append(template_helpers.EZTItem(
        val=lab_val, docstring=label_docs.get(full_label_lower, ''), idx=idx))

  return values


class FieldDefView(template_helpers.PBProxy):
  """Wrapper class to make it easier to display field definitions via EZT."""

  def __init__(self, field_def, config, user_views=None, approval_def=None):
    super(FieldDefView, self).__init__(field_def)

    self.type_name = str(field_def.field_type)
    self.field_def = field_def

    self.choices = []
    if field_def.field_type == tracker_pb2.FieldTypes.ENUM_TYPE:
      self.choices = tracker_helpers.LabelsMaskedByFields(
          config, [field_def.field_name], trim_prefix=True)

    self.approvers = []
    self.survey = ''
    self.survey_questions = []
    if (approval_def and
        field_def.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE):
      self.approvers = [user_views.get(approver_id) for
                             approver_id in approval_def.approver_ids]
      if approval_def.survey:
        self.survey = approval_def.survey
        self.survey_questions = self.survey.split('\n')


    self.docstring_short = template_helpers.FitUnsafeText(
        field_def.docstring, 200)
    self.validate_help = None

    if field_def.is_required:
      self.importance = 'required'
    elif field_def.is_niche:
      self.importance = 'niche'
    else:
      self.importance = 'normal'

    if field_def.min_value is not None:
      self.min_value = field_def.min_value
      self.validate_help = 'Value must be >= %d' % field_def.min_value
    else:
      self.min_value = None  # Otherwise it would default to 0

    if field_def.max_value is not None:
      self.max_value = field_def.max_value
      self.validate_help = 'Value must be <= %d' % field_def.max_value
    else:
      self.max_value = None  # Otherwise it would default to 0

    if field_def.min_value is not None and field_def.max_value is not None:
      self.validate_help = 'Value must be between %d and %d' % (
          field_def.min_value, field_def.max_value)

    if field_def.regex:
      self.validate_help = 'Value must match regex: %s' % field_def.regex

    if field_def.needs_member:
      self.validate_help = 'Value must be a project member'

    if field_def.needs_perm:
      self.validate_help = (
          'Value must be a project member with permission %s' %
          field_def.needs_perm)

    self.date_action_str = str(field_def.date_action or 'no_action').lower()

    self.admins = []
    if user_views:
      self.admins = [user_views.get(admin_id)
                     for admin_id in field_def.admin_ids]

    self.editors = []
    if user_views:
      self.editors = [
          user_views.get(editor_id) for editor_id in field_def.editor_ids
      ]

    if field_def.approval_id:
      self.is_approval_subfield = ezt.boolean(True)
      self.parent_approval_name = tracker_bizobj.FindFieldDefByID(
          field_def.approval_id, config).field_name
    else:
      self.is_approval_subfield = ezt.boolean(False)

    self.is_phase_field = ezt.boolean(field_def.is_phase_field)
    self.is_restricted_field = ezt.boolean(field_def.is_restricted_field)


class IssueTemplateView(template_helpers.PBProxy):
  """Wrapper class to make it easier to display an issue template via EZT."""

  def __init__(self, mr, template, user_service, config):
    super(IssueTemplateView, self).__init__(template)

    self.ownername = ''
    try:
      self.owner_view = framework_views.MakeUserView(
          mr.cnxn, user_service, template.owner_id)
    except exceptions.NoSuchUserException:
      self.owner_view = None
    if self.owner_view:
      self.ownername = self.owner_view.email

    self.admin_views = list(framework_views.MakeAllUserViews(
        mr.cnxn, user_service, template.admin_ids).values())
    self.admin_names = ', '.join(sorted([
        admin_view.email for admin_view in self.admin_views]))

    self.summary_must_be_edited = ezt.boolean(template.summary_must_be_edited)
    self.members_only = ezt.boolean(template.members_only)
    self.owner_defaults_to_member = ezt.boolean(
        template.owner_defaults_to_member)
    self.component_required = ezt.boolean(template.component_required)

    component_paths = []
    for component_id in template.component_ids:
      component_paths.append(
          tracker_bizobj.FindComponentDefByID(component_id, config).path)
    self.components = ', '.join(component_paths)

    self.can_view = ezt.boolean(permissions.CanViewTemplate(
        mr.auth.effective_ids, mr.perms, mr.project, template))
    self.can_edit = ezt.boolean(permissions.CanEditTemplate(
        mr.auth.effective_ids, mr.perms, mr.project, template))

    field_name_set = {fd.field_name.lower() for fd in config.field_defs
                      if fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE and
                      not fd.is_deleted}  # TODO(jrobbins): restrictions
    non_masked_labels = [
        lab for lab in template.labels
        if not tracker_bizobj.LabelIsMaskedByField(lab, field_name_set)]

    for i, label in enumerate(non_masked_labels):
      setattr(self, 'label%d' % i, label)
    for i in range(len(non_masked_labels), framework_constants.MAX_LABELS):
      setattr(self, 'label%d' % i, '')

    field_user_views = MakeFieldUserViews(mr.cnxn, template, user_service)

    self.field_values = []
    for fv in template.field_values:
      self.field_values.append(template_helpers.EZTItem(
          field_id=fv.field_id,
          val=tracker_bizobj.GetFieldValue(fv, field_user_views),
          idx=len(self.field_values)))

    self.complete_field_values = MakeAllFieldValueViews(
        config, template.labels, [], template.field_values, field_user_views)

    # Templates only display and edit the first value of multi-valued fields, so
    # expose a single value, if any.
    # TODO(jrobbins): Fully support multi-valued fields in templates.
    for idx, field_value_view in enumerate(self.complete_field_values):
      field_value_view.idx = idx
      if field_value_view.values:
        field_value_view.val = field_value_view.values[0].val
      else:
        field_value_view.val = None


def MakeFieldUserViews(cnxn, template, user_service):
  """Return {user_id: user_view} for users in template field values."""
  field_user_ids = [
      fv.user_id for fv in template.field_values
      if fv.user_id]
  field_user_views = framework_views.MakeAllUserViews(
      cnxn, user_service, field_user_ids)
  return field_user_views


class ConfigView(template_helpers.PBProxy):
  """Make it easy to display most fields of a ProjectIssueConfig in EZT."""

  def __init__(self, mr, services, config, template=None,
               load_all_templates=False):
    """Gather data for the issue section of a project admin page.

    Args:
      mr: MonorailRequest, including a database connection, the current
          project, and authenticated user IDs.
      services: Persist services with ProjectService, ConfigService,
          TemplateService and UserService included.
      config: ProjectIssueConfig for the current project..
      template (TemplateDef, optional): the current template.
      load_all_templates (boolean): default False. If true loads self.templates.

    Returns:
      Project info in a dict suitable for EZT.
    """
    super(ConfigView, self).__init__(config)
    self.open_statuses = []
    self.closed_statuses = []
    for wks in config.well_known_statuses:
      item = template_helpers.EZTItem(
          name=wks.status,
          name_padded=wks.status.ljust(20),
          commented='#' if wks.deprecated else '',
          docstring=wks.status_docstring)
      if tracker_helpers.MeansOpenInProject(wks.status, config):
        self.open_statuses.append(item)
      else:
        self.closed_statuses.append(item)

    is_member = framework_bizobj.UserIsInProject(
        mr.project, mr.auth.effective_ids)
    template_set = services.template.GetTemplateSetForProject(mr.cnxn,
        config.project_id)

    # Filter non-viewable templates
    self.template_names = []
    for _, template_name, members_only in template_set:
      if members_only and not is_member:
        continue
      self.template_names.append(template_name)

    if load_all_templates:
      templates = services.template.GetProjectTemplates(mr.cnxn,
          config.project_id)
      self.templates = [
          IssueTemplateView(mr, tmpl, services.user, config)
          for tmpl in templates]
      for index, template_view in enumerate(self.templates):
        template_view.index = index

    if template:
      self.template_view = IssueTemplateView(mr, template, services.user,
          config)

    self.field_names = [  # TODO(jrobbins): field-level controls
        fd.field_name for fd in config.field_defs if
        fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE and
        not fd.is_deleted]
    self.issue_labels = tracker_helpers.LabelsNotMaskedByFields(
        config, self.field_names)
    self.excl_prefixes = [
        prefix.lower() for prefix in config.exclusive_label_prefixes]
    self.restrict_to_known = ezt.boolean(config.restrict_to_known)

    self.default_col_spec = (
        config.default_col_spec or tracker_constants.DEFAULT_COL_SPEC)


def StatusDefsAsText(config):
  """Return two strings for editing open and closed status definitions."""
  open_lines = []
  closed_lines = []
  for wks in config.well_known_statuses:
    line = '%s%s%s%s' % (
      '#' if wks.deprecated else '',
      wks.status.ljust(20),
      '\t= ' if wks.status_docstring else '',
      wks.status_docstring)

    if tracker_helpers.MeansOpenInProject(wks.status, config):
      open_lines.append(line)
    else:
      closed_lines.append(line)

  open_text = '\n'.join(open_lines)
  closed_text = '\n'.join(closed_lines)
  logging.info('open_text is \n%s', open_text)
  logging.info('closed_text is \n%s', closed_text)
  return open_text, closed_text


def LabelDefsAsText(config):
  """Return a string for editing label definitions."""
  field_names = [fd.field_name for fd in config.field_defs
                 if fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE
                 and not fd.is_deleted]
  masked_labels = tracker_helpers.LabelsMaskedByFields(config, field_names)
  masked_set = set(masked.name for masked in masked_labels)

  label_def_lines = []
  for wkl in config.well_known_labels:
    if wkl.label in masked_set:
      continue
    line = '%s%s%s%s' % (
      '#' if wkl.deprecated else '',
      wkl.label.ljust(20),
      '\t= ' if wkl.label_docstring else '',
      wkl.label_docstring)
    label_def_lines.append(line)

  labels_text = '\n'.join(label_def_lines)
  logging.info('labels_text is \n%s', labels_text)
  return labels_text
