# 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

"""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 proto 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
