# 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 classes to make it easy to display framework objects in EZT."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import time

import ezt

from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
from framework import permissions
from framework import template_helpers
from framework import timestr
from mrproto import user_pb2
from services import client_config_svc
import settings


_LABEL_DISPLAY_CHARS = 30
_LABEL_PART_DISPLAY_CHARS = 15


class LabelView(object):
  """Wrapper class that makes it easier to display a label via EZT."""

  def __init__(self, label, config):
    """Make several values related to this label available as attrs.

    Args:
      label: artifact label string.  E.g., 'Priority-High' or 'Frontend'.
      config: PB with a well_known_labels list, or None.
    """
    self.name = label
    self.is_restrict = ezt.boolean(permissions.IsRestrictLabel(label))

    self.docstring = ''
    if config:
      for wkl in config.well_known_labels:
        if label.lower() == wkl.label.lower():
          self.docstring = wkl.label_docstring

    if '-' in label:
      self.prefix, self.value = label.split('-', 1)
    else:
      self.prefix, self.value = '', label


class StatusView(object):
  """Wrapper class that makes it easier to display a status via EZT."""

  def __init__(self, status, config):
    """Make several values related to this status available as attrs.

    Args:
      status: artifact status string.  E.g., 'New' or 'Accepted'.
      config: PB with a well_known_statuses list, or None.
    """

    self.name = status

    self.docstring = ''
    self.means_open = ezt.boolean(True)
    if config:
      for wks in config.well_known_statuses:
        if status.lower() == wks.status.lower():
          self.docstring = wks.status_docstring
          self.means_open = ezt.boolean(wks.means_open)


class UserView(object):
  """Wrapper class to easily display basic user information in a template."""

  def __init__(self, user, is_group=False):
    self.user = user
    self.is_group = is_group
    email = user.email or ''
    self.user_id = user.user_id
    self.email = email
    if user.obscure_email:
      self.profile_url = '/u/%s/' % user.user_id
    else:
      self.profile_url = '/u/%s/' % email
    self.obscure_email = user.obscure_email
    self.banned = ''

    (self.username, self.domain, self.obscured_username,
     obscured_email) = framework_bizobj.ParseAndObscureAddress(email)
    # No need to obfuscate or reveal client email.
    # Instead display a human-readable username.
    if self.user_id == framework_constants.DELETED_USER_ID:
      self.display_name = framework_constants.DELETED_USER_NAME
      self.obscure_email = ''
      self.profile_url = ''
    elif self.email in client_config_svc.GetServiceAccountMap():
      self.display_name = client_config_svc.GetServiceAccountMap()[self.email]
    elif not self.obscure_email:
      self.display_name = email
    else:
      self.display_name = obscured_email

    self.avail_message, self.avail_state = (
        framework_helpers.GetUserAvailability(user, is_group))
    self.avail_message_short = template_helpers.FitUnsafeText(
        self.avail_message, 35)

  def RevealEmail(self):
    if not self.email:
      return
    if self.email not in client_config_svc.GetServiceAccountMap():
      self.obscure_email = False
      self.display_name = self.email
      self.profile_url = '/u/%s/' % self.email


def MakeAllUserViews(
    cnxn, user_service, *list_of_user_id_lists, **kw):
  """Make a dict {user_id: user_view, ...} for all user IDs given."""
  distinct_user_ids = set()
  distinct_user_ids.update(*list_of_user_id_lists)
  if None in distinct_user_ids:
    distinct_user_ids.remove(None)
  group_ids = kw.get('group_ids', [])
  user_dict = user_service.GetUsersByIDs(cnxn, distinct_user_ids)
  return {user_id: UserView(user_pb, is_group=user_id in group_ids)
          for user_id, user_pb in user_dict.items()}


def MakeUserView(cnxn, user_service, user_id):
  """Make a UserView for the given user ID."""
  user = user_service.GetUser(cnxn, user_id)
  return UserView(user)


def StuffUserView(user_id, email, obscure_email):
  """Construct a UserView with the given parameters for testing."""
  user = user_pb2.MakeUser(user_id, email=email, obscure_email=obscure_email)
  return UserView(user)


# TODO(https://crbug.com/monorail/8192): Remove optional project.
def RevealAllEmailsToMembers(cnxn, services, auth, users_by_id, project=None):
  # type: (MonorailConnection, Services, AuthData, Collection[user_pb2.User],
  #     Optional[project_pb2.Project] -> None)
  """Reveal emails based on the authenticated user.

  The actual behavior can be determined by looking into
  framework_bizobj.ShouldRevealEmail. Look at https://crbug.com/monorail/8030
  for context.
  This method should be deleted when endpoints and ezt pages are deprecated.

  Args:
    cnxn: MonorailConnection to the database.
    services: Services object for connections to backend services.
    auth: AuthData object that identifies the logged in user.
    users_by_id: dictionary of UserView's that might be displayed.
    project: Optional Project PB for the current project.

  Returns:
    Nothing, but the UserViews in users_by_id may be modified to
    publish email address.
  """
  if project:
    for user_view in users_by_id.values():
      if framework_bizobj.DeprecatedShouldRevealEmail(auth, project,
                                                      user_view.email):
        user_view.RevealEmail()
  else:
    viewable_users = framework_bizobj.FilterViewableEmails(
        cnxn, services, auth, users_by_id.values())
    for user_view in viewable_users:
      user_view.RevealEmail()


def RevealAllEmails(users_by_id):
  """Allow anyone to see unobscured email addresses of project members.

  The modified view objects should only be used to generate views for other
  project members.

  Args:
    users_by_id: dictionary of UserViews that will be displayed.

  Returns:
    Nothing, but the UserViews in users_by_id may be modified to
    publish email address.
  """
  for user_view in users_by_id.values():
    user_view.RevealEmail()


def GetViewedUserDisplayName(mr):
  """Get display name of the viewed user given the logged-in user."""
  # Do not obscure email if current user is a site admin. Do not obscure
  # email if current user is viewing their own profile. For all other
  # cases do whatever obscure_email setting for the user is.
  viewing_self = mr.auth.user_id == mr.viewed_user_auth.user_id
  email_obscured = (not(mr.auth.user_pb.is_site_admin or viewing_self)
                    and mr.viewed_user_auth.user_view.obscure_email)
  if email_obscured:
    (_username, _domain, _obscured_username,
     obscured_email) = framework_bizobj.ParseAndObscureAddress(
         mr.viewed_user_auth.email)
    viewed_user_display_name = obscured_email
  else:
    viewed_user_display_name = mr.viewed_user_auth.email

  return viewed_user_display_name
