# 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

"""A class to display a paginated list of project members.

This page lists owners, members, and contribtors.  For each
member, we display their username, permission system role + extra
perms, and notes on their involvement in the project.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import time

import ezt

from businesslogic import work_env
from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
from framework import framework_views
from framework import paginate
from framework import permissions
from framework import servlet
from framework import urls
from project import project_helpers
from project import project_views

MEMBERS_PER_PAGE = 50


class PeopleList(servlet.Servlet):
  """People list page shows a paginatied list of project members."""

  _PAGE_TEMPLATE = 'project/people-list-page.ezt'
  _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PEOPLE

  def AssertBasePermission(self, mr):
    super(PeopleList, self).AssertBasePermission(mr)
    # For now, contributors who cannot view other contributors are further
    # restricted from viewing any part of the member list or detail pages.
    if not permissions.CanViewContributorList(mr, mr.project):
      raise permissions.PermissionException(
          'User is not allowed to view the project people list')

  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page."""
    all_members = (mr.project.owner_ids +
                   mr.project.committer_ids +
                   mr.project.contributor_ids)

    with mr.profiler.Phase('gathering members on this page'):
      users_by_id = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, all_members)
      framework_views.RevealAllEmailsToMembers(
          mr.cnxn, self.services, mr.auth, users_by_id, mr.project)

    # TODO(jrobbins): re-implement FindUntrustedGroups()
    untrusted_user_group_proxies = []

    with mr.profiler.Phase('gathering commitments (notes)'):
      project_commitments = self.services.project.GetProjectCommitments(
          mr.cnxn, mr.project_id)

    with mr.profiler.Phase('gathering autocomple exclusion ids'):
      group_ids = set(self.services.usergroup.DetermineWhichUserIDsAreGroups(
        mr.cnxn, all_members))
      (ac_exclusion_ids, no_expand_ids
       ) = self.services.project.GetProjectAutocompleteExclusion(
          mr.cnxn, mr.project_id)

    with mr.profiler.Phase('making member views'):
      owner_views = self._MakeMemberViews(
          mr.auth.user_id, users_by_id, mr.project.owner_ids, mr.project,
          project_commitments, ac_exclusion_ids, no_expand_ids, group_ids)
      committer_views = self._MakeMemberViews(
          mr.auth.user_id, users_by_id, mr.project.committer_ids, mr.project,
          project_commitments, ac_exclusion_ids, no_expand_ids, group_ids)
      contributor_views = self._MakeMemberViews(
          mr.auth.user_id, users_by_id, mr.project.contributor_ids, mr.project,
          project_commitments, ac_exclusion_ids, no_expand_ids, group_ids)
      all_member_views = owner_views + committer_views + contributor_views

    url_params = [(name, mr.GetParam(name)) for name in
                  framework_helpers.RECOGNIZED_PARAMS]
    pagination = paginate.ArtifactPagination(
        all_member_views, mr.GetPositiveIntParam('num', MEMBERS_PER_PAGE),
        mr.GetPositiveIntParam('start'), mr.project_name, urls.PEOPLE_LIST,
        url_params=url_params)

    offer_membership_editing = mr.perms.HasPerm(
        permissions.EDIT_PROJECT, mr.auth.user_id, mr.project)

    check_abandonment = permissions.ShouldCheckForAbandonment(mr)

    newly_added_views = [mv for mv in all_member_views
                         if str(mv.user.user_id) in mr.GetParam('new', [])]

    return {
        'pagination': pagination,
        'subtab_mode': None,
        'offer_membership_editing': ezt.boolean(offer_membership_editing),
        'initial_add_members': '',
        'initially_expand_form': ezt.boolean(False),
        'untrusted_user_groups': untrusted_user_group_proxies,
        'check_abandonment': ezt.boolean(check_abandonment),
        'total_num_owners': len(mr.project.owner_ids),
        'newly_added_views': newly_added_views,
        'is_hotlist': ezt.boolean(False),
        }

  def GatherHelpData(self, mr, page_data):
    """Return a dict of values to drive on-page user help.

    Args:
      mr: common information parsed from the HTTP request.
      page_data: Dictionary of base and page template data.

    Returns:
      A dict of values to drive on-page user help, to be added to page_data.
    """
    help_data = super(PeopleList, self).GatherHelpData(mr, page_data)
    with work_env.WorkEnv(mr, self.services) as we:
      userprefs = we.GetUserPrefs(mr.auth.user_id)
    dismissed = [
        pv.name for pv in userprefs.prefs if pv.value == 'true']
    if (mr.auth.user_id and
        not framework_bizobj.UserIsInProject(
            mr.project, mr.auth.effective_ids) and
        'how_to_join_project' not in dismissed):
      help_data['cue'] = 'how_to_join_project'

    return help_data

  def _MakeMemberViews(
      self, logged_in_user_id, users_by_id, member_ids, project,
      project_commitments, ac_exclusion_ids, no_expand_ids, group_ids):
    """Return a sorted list of MemberViews for display by EZT."""
    member_views = [
        project_views.MemberView(
            logged_in_user_id, member_id, users_by_id[member_id], project,
            project_commitments,
            ac_exclusion=(member_id in ac_exclusion_ids),
            no_expand=(member_id in no_expand_ids),
            is_group=(member_id in group_ids))
        for member_id in member_ids]
    member_views.sort(key=lambda mv: mv.user.email)
    return member_views

  def ProcessFormData(self, mr, post_data):
    """Process the posted form."""
    permit_edit = mr.perms.HasPerm(
        permissions.EDIT_PROJECT, mr.auth.user_id, mr.project)
    if not permit_edit:
      raise permissions.PermissionException(
          'User is not permitted to edit project membership')

    if 'addbtn' in post_data:
      return self.ProcessAddMembers(mr, post_data)
    elif 'removebtn' in post_data:
      return self.ProcessRemoveMembers(mr, post_data)

  def ProcessAddMembers(self, mr, post_data):
    """Process the user's request to add members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
    # 1. Parse and validate user input.
    new_member_ids = project_helpers.ParseUsernames(
        mr.cnxn, self.services.user, post_data.get('addmembers'))
    role = post_data['role']

    (owner_ids, committer_ids,
     contributor_ids) = project_helpers.MembersWithGivenIDs(
        mr.project, new_member_ids, role)

    total_people = len(owner_ids) + len(committer_ids) + len(contributor_ids)
    if total_people > framework_constants.MAX_PROJECT_PEOPLE:
      mr.errors.addmembers = (
          'Too many project members.  The combined limit is %d.' %
          framework_constants.MAX_PROJECT_PEOPLE)

    # 2. Call services layer to save changes.
    if not mr.errors.AnyErrors():
      self.services.project.UpdateProjectRoles(
          mr.cnxn, mr.project.project_id,
          owner_ids, committer_ids, contributor_ids)

    # 3. Determine the next page in the UI flow.
    if mr.errors.AnyErrors():
      add_members_str = post_data.get('addmembers', '')
      self.PleaseCorrect(
          mr, initial_add_members=add_members_str, initially_expand_form=True)
    else:
      return framework_helpers.FormatAbsoluteURL(
          mr, urls.PEOPLE_LIST, saved=1, ts=int(time.time()),
          new=','.join([str(u) for u in new_member_ids]))

  def ProcessRemoveMembers(self, mr, post_data):
    """Process the user's request to remove members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
    # 1. Parse and validate user input.
    remove_strs = post_data.getall('remove')
    # TODO(crbug.com/monorail/10936): getall in Flask is getlist
    # remove_strs = post_data.getlist('remove')
    logging.info('remove_strs = %r', remove_strs)
    remove_ids = set(
        self.services.user.LookupUserIDs(mr.cnxn, remove_strs).values())
    (owner_ids, committer_ids,
     contributor_ids) = project_helpers.MembersWithoutGivenIDs(
        mr.project, remove_ids)

    # 2. Call services layer to save changes.
    self.services.project.UpdateProjectRoles(
        mr.cnxn, mr.project.project_id, owner_ids, committer_ids,
        contributor_ids)

    # 3. Determine the next page in the UI flow.
    return framework_helpers.FormatAbsoluteURL(
        mr, urls.PEOPLE_LIST, saved=1, ts=int(time.time()))

  # def GetPeopleListPage(self, **kwargs):
  #   return self.handler(**kwargs)

  # def PostPeopleListPage(self, **kwargs):
  #   return self.handler(**kwargs)
