# 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 for the user profile page ("my page")."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import time
import json

import ezt

import settings
from businesslogic import work_env
from framework import framework_helpers
from framework import framework_views
from framework import permissions
from framework import servlet
from framework import timestr
from framework import xsrf
from project import project_views
from sitewide import sitewide_helpers


class UserProfile(servlet.Servlet):
  """Shows a page of information about a user."""

  _PAGE_TEMPLATE = 'sitewide/user-profile-page.ezt'

  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page."""
    viewed_user = mr.viewed_user_auth.user_pb
    if self.services.usergroup.GetGroupSettings(
        mr.cnxn, mr.viewed_user_auth.user_id):
      url = framework_helpers.FormatAbsoluteURL(
          mr, '/g/%s/' % viewed_user.email, include_project=False)
      self.redirect(url, abort=True)  # Show group page instead.

    with work_env.WorkEnv(mr, self.services) as we:
      project_lists = we.GetUserProjects(mr.viewed_user_auth.effective_ids)

      (visible_ownership, visible_archived, visible_membership,
       visible_contrib) = project_lists

    with mr.profiler.Phase('Getting user groups'):
      group_settings = self.services.usergroup.GetAllGroupSettings(
          mr.cnxn, mr.viewed_user_auth.effective_ids)
      member_ids, owner_ids = self.services.usergroup.LookupAllMembers(
          mr.cnxn, list(group_settings.keys()))
      friend_project_ids = [] # TODO(issue 4202): implement this.
      visible_group_ids = []
      for group_id in group_settings:
        if permissions.CanViewGroupMembers(
            mr.perms, mr.auth.effective_ids, group_settings[group_id],
            member_ids[group_id], owner_ids[group_id], friend_project_ids):
          visible_group_ids.append(group_id)

      user_group_views = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, visible_group_ids)
      user_group_views = sorted(
          list(user_group_views.values()), key=lambda ugv: ugv.email)

    with mr.profiler.Phase('Getting linked accounts'):
      linked_parent = None
      linked_children = []
      linked_views = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user,
          [viewed_user.linked_parent_id],
          viewed_user.linked_child_ids)
      if viewed_user.linked_parent_id:
        linked_parent = linked_views[viewed_user.linked_parent_id]
      if viewed_user.linked_child_ids:
        linked_children = [
          linked_views[child_id] for child_id in viewed_user.linked_child_ids]
      offer_unlink = (mr.auth.user_id == viewed_user.user_id or
                      mr.auth.user_id in linked_views)

    incoming_invite_users = []
    outgoing_invite_users = []
    possible_parent_accounts = []
    can_edit_invites = mr.auth.user_id == mr.viewed_user_auth.user_id
    display_link_invites = can_edit_invites or mr.auth.user_pb.is_site_admin
    # TODO(jrobbins): allow site admin to edit invites for other users.
    if display_link_invites:
      with work_env.WorkEnv(mr, self.services, phase='Getting link invites'):
        incoming_invite_ids, outgoing_invite_ids = we.GetPendingLinkedInvites(
            user_id=viewed_user.user_id)
        invite_views = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, incoming_invite_ids, outgoing_invite_ids)
        incoming_invite_users = [
            invite_views[uid] for uid in incoming_invite_ids]
        outgoing_invite_users = [
            invite_views[uid] for uid in outgoing_invite_ids]
        possible_parent_accounts = _ComputePossibleParentAccounts(
            we, mr.viewed_user_auth.user_view, linked_parent, linked_children)

    viewed_user_display_name = framework_views.GetViewedUserDisplayName(mr)

    with work_env.WorkEnv(mr, self.services) as we:
      starred_projects = we.ListStarredProjects(
          viewed_user_id=mr.viewed_user_auth.user_id)
      logged_in_starred = we.ListStarredProjects()
      logged_in_starred_pids = {p.project_id for p in logged_in_starred}

    starred_user_ids = self.services.user_star.LookupStarredItemIDs(
        mr.cnxn, mr.viewed_user_auth.user_id)
    starred_user_dict = framework_views.MakeAllUserViews(
        mr.cnxn, self.services.user, starred_user_ids)
    starred_users = list(starred_user_dict.values())
    starred_users_json = json.dumps(
      [uv.display_name for uv in starred_users])

    is_user_starred = self._IsUserStarred(
        mr.cnxn, mr.auth.user_id, mr.viewed_user_auth.user_id)

    if viewed_user.last_visit_timestamp:
      last_visit_str = timestr.FormatRelativeDate(
          viewed_user.last_visit_timestamp, days_only=True)
      last_visit_str = last_visit_str or 'Less than 2 days ago'
    else:
      last_visit_str = 'Never'

    if viewed_user.email_bounce_timestamp:
      last_bounce_str = timestr.FormatRelativeDate(
          viewed_user.email_bounce_timestamp, days_only=True)
      last_bounce_str = last_bounce_str or 'Less than 2 days ago'
    else:
      last_bounce_str = None

    can_ban = permissions.CanBan(mr, self.services)
    viewed_user_is_spammer = viewed_user.banned.lower() == 'spam'
    viewed_user_may_be_spammer = not viewed_user_is_spammer
    all_projects = self.services.project.GetAllProjects(mr.cnxn)
    for project_id in all_projects:
      project = all_projects[project_id]
      viewed_user_perms = permissions.GetPermissions(viewed_user,
          mr.viewed_user_auth.effective_ids, project)
      if (viewed_user_perms != permissions.EMPTY_PERMISSIONSET and
          viewed_user_perms != permissions.USER_PERMISSIONSET):
        viewed_user_may_be_spammer = False

    ban_token = None
    ban_spammer_token = None
    if mr.auth.user_id and can_ban:
      form_token_path = mr.request.path + 'ban.do'
      ban_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path)
      form_token_path = mr.request.path + 'banSpammer.do'
      ban_spammer_token = xsrf.GenerateToken(mr.auth.user_id, form_token_path)

    can_delete_user = permissions.CanExpungeUsers(mr)

    page_data = {
        'user_tab_mode': 'st2',
        'viewed_user_display_name': viewed_user_display_name,
        'viewed_user_may_be_spammer': ezt.boolean(viewed_user_may_be_spammer),
        'viewed_user_is_spammer': ezt.boolean(viewed_user_is_spammer),
        'viewed_user_is_banned': ezt.boolean(viewed_user.banned),
        'owner_of_projects': [
            project_views.ProjectView(
                p, starred=p.project_id in logged_in_starred_pids)
            for p in visible_ownership],
        'committer_of_projects': [
            project_views.ProjectView(
                p, starred=p.project_id in logged_in_starred_pids)
            for p in visible_membership],
        'contributor_to_projects': [
            project_views.ProjectView(
                p, starred=p.project_id in logged_in_starred_pids)
            for p in visible_contrib],
        'owner_of_archived_projects': [
            project_views.ProjectView(p) for p in visible_archived],
        'starred_projects': [
            project_views.ProjectView(
                p, starred=p.project_id in logged_in_starred_pids)
            for p in starred_projects],
        'starred_users': starred_users,
        'starred_users_json': starred_users_json,
        'is_user_starred': ezt.boolean(is_user_starred),
        'viewing_user_page': ezt.boolean(True),
        'last_visit_str': last_visit_str,
        'last_bounce_str': last_bounce_str,
        'vacation_message': viewed_user.vacation_message,
        'can_ban': ezt.boolean(can_ban),
        'ban_token': ban_token,
        'ban_spammer_token': ban_spammer_token,
        'user_groups': user_group_views,
        'linked_parent': linked_parent,
        'linked_children': linked_children,
        'incoming_invite_users': incoming_invite_users,
        'outgoing_invite_users': outgoing_invite_users,
        'possible_parent_accounts': possible_parent_accounts,
        'can_edit_invites': ezt.boolean(can_edit_invites),
        'offer_unlink': ezt.boolean(offer_unlink),
        'can_delete_user': ezt.boolean(can_delete_user),
        }

    viewed_user_prefs = None
    if mr.perms.HasPerm(permissions.EDIT_OTHER_USERS, None, None):
      with work_env.WorkEnv(mr, self.services) as we:
        viewed_user_prefs = we.GetUserPrefs(mr.viewed_user_auth.user_id)

    user_settings = (
        framework_helpers.UserSettings.GatherUnifiedSettingsPageData(
        mr.auth.user_id, mr.viewed_user_auth.user_view, viewed_user,
        viewed_user_prefs))
    page_data.update(user_settings)

    return page_data

  def _IsUserStarred(self, cnxn, logged_in_user_id, viewed_user_id):
    """Return whether the logged in user starred the viewed user."""
    if logged_in_user_id:
      return self.services.user_star.IsItemStarredBy(
          cnxn, viewed_user_id, logged_in_user_id)
    return False

  def ProcessFormData(self, mr, post_data):
    """Process the posted form."""
    has_admin_perm = mr.perms.HasPerm(permissions.EDIT_OTHER_USERS, None, None)
    with work_env.WorkEnv(mr, self.services) as we:
      framework_helpers.UserSettings.ProcessSettingsForm(
          we, post_data, mr.viewed_user_auth.user_pb, admin=has_admin_perm)

    # TODO(jrobbins): Check all calls to FormatAbsoluteURL for include_project.
    return framework_helpers.FormatAbsoluteURL(
        mr, mr.viewed_user_auth.user_view.profile_url, include_project=False,
        saved=1, ts=int(time.time()))


def _ComputePossibleParentAccounts(
    we, user_view, linked_parent, linked_children):
  """Return a list of email addresses of possible parent accounts."""
  if not user_view:
    return []  # Anon user cannot link to any account.
  if linked_parent or linked_children:
    return []  # If account is already linked in any way, don't offer.
  possible_domains = settings.linkable_domains.get(user_view.domain, [])
  possible_emails = ['%s@%s' % (user_view.username, domain)
                     for domain in possible_domains]
  found_users, _ = we.ListReferencedUsers(possible_emails)
  found_emails = [user.email for user in found_users]
  return found_emails


class UserProfilePolymer(UserProfile):
  """New Polymer version of user profiles in Monorail."""

  _PAGE_TEMPLATE = 'sitewide/user-profile-page-polymer.ezt'


class BanUser(servlet.Servlet):
  """Bans or un-bans a user."""

  def ProcessFormData(self, mr, post_data):
    """Process the posted form."""
    if not permissions.CanBan(mr, self.services):
      raise permissions.PermissionException(
          "You do not have permission to ban users.")

    framework_helpers.UserSettings.ProcessBanForm(
        mr.cnxn, self.services.user, post_data, mr.viewed_user_auth.user_id,
        mr.viewed_user_auth.user_pb)

    # TODO(jrobbins): Check all calls to FormatAbsoluteURL for include_project.
    return framework_helpers.FormatAbsoluteURL(
        mr, mr.viewed_user_auth.user_view.profile_url, include_project=False,
        saved=1, ts=int(time.time()))
