# 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 set of functions that provide persistence for projects.

This module provides functions to get, update, create, and (in some
cases) delete each type of project business object.  It provides
a logical persistence layer on top of the database.

Business objects are described in project_pb2.py.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import collections
import logging
import time

import settings
from framework import exceptions
from framework import framework_constants
from framework import framework_helpers
from framework import permissions
from framework import sql
from services import caches
from project import project_helpers
from proto import project_pb2


PROJECT_TABLE_NAME = 'Project'
USER2PROJECT_TABLE_NAME = 'User2Project'
EXTRAPERM_TABLE_NAME = 'ExtraPerm'
MEMBERNOTES_TABLE_NAME = 'MemberNotes'
USERGROUPPROJECTS_TABLE_NAME = 'Group2Project'
AUTOCOMPLETEEXCLUSION_TABLE_NAME = 'AutocompleteExclusion'

PROJECT_COLS = [
    'project_id', 'project_name', 'summary', 'description', 'state', 'access',
    'read_only_reason', 'state_reason', 'delete_time', 'issue_notify_address',
    'attachment_bytes_used', 'attachment_quota', 'cached_content_timestamp',
    'recent_activity_timestamp', 'moved_to', 'process_inbound_email',
    'only_owners_remove_restrictions', 'only_owners_see_contributors',
    'revision_url_format', 'home_page', 'docs_url', 'source_url', 'logo_gcs_id',
    'logo_file_name', 'issue_notify_always_detailed'
]
USER2PROJECT_COLS = ['project_id', 'user_id', 'role_name']
EXTRAPERM_COLS = ['project_id', 'user_id', 'perm']
MEMBERNOTES_COLS = ['project_id', 'user_id', 'notes']
AUTOCOMPLETEEXCLUSION_COLS = [
    'project_id', 'user_id', 'ac_exclude', 'no_expand']

RECENT_ACTIVITY_THRESHOLD = framework_constants.SECS_PER_HOUR


class ProjectTwoLevelCache(caches.AbstractTwoLevelCache):
  """Class to manage both RAM and memcache for Project PBs."""

  def __init__(self, cachemanager, project_service):
    super(ProjectTwoLevelCache, self).__init__(
        cachemanager, 'project', 'project:', project_pb2.Project)
    self.project_service = project_service

  def _DeserializeProjects(
      self, project_rows, role_rows, extraperm_rows):
    """Convert database rows into a dictionary of Project PB keyed by ID."""
    project_dict = {}

    for project_row in project_rows:
      (
          project_id, project_name, summary, description, state_name,
          access_name, read_only_reason, state_reason, delete_time,
          issue_notify_address, attachment_bytes_used, attachment_quota, cct,
          recent_activity_timestamp, moved_to, process_inbound_email, oorr,
          oosc, revision_url_format, home_page, docs_url, source_url,
          logo_gcs_id, logo_file_name,
          issue_notify_always_detailed) = project_row
      project = project_pb2.Project()
      project.project_id = project_id
      project.project_name = project_name
      project.summary = summary
      project.description = description
      project.state = project_pb2.ProjectState(state_name.upper())
      project.state_reason = state_reason or ''
      project.access = project_pb2.ProjectAccess(access_name.upper())
      project.read_only_reason = read_only_reason or ''
      project.issue_notify_address = issue_notify_address or ''
      project.attachment_bytes_used = attachment_bytes_used or 0
      project.attachment_quota = attachment_quota
      project.recent_activity = recent_activity_timestamp or 0
      project.cached_content_timestamp = cct or 0
      project.delete_time = delete_time or 0
      project.moved_to = moved_to or ''
      project.process_inbound_email = bool(process_inbound_email)
      project.only_owners_remove_restrictions = bool(oorr)
      project.only_owners_see_contributors = bool(oosc)
      project.revision_url_format = revision_url_format or ''
      project.home_page = home_page or ''
      project.docs_url = docs_url or ''
      project.source_url = source_url or ''
      project.logo_gcs_id = logo_gcs_id or ''
      project.logo_file_name = logo_file_name or ''
      project.issue_notify_always_detailed = bool(issue_notify_always_detailed)
      project_dict[project_id] = project

    for project_id, user_id, role_name in role_rows:
      project = project_dict[project_id]
      if role_name == 'owner':
        project.owner_ids.append(user_id)
      elif role_name == 'committer':
        project.committer_ids.append(user_id)
      elif role_name == 'contributor':
        project.contributor_ids.append(user_id)

    perms = {}
    for project_id, user_id, perm in extraperm_rows:
      perms.setdefault(project_id, {}).setdefault(user_id, []).append(perm)

    for project_id, perms_by_user in perms.items():
      project = project_dict[project_id]
      for user_id, extra_perms in sorted(perms_by_user.items()):
        project.extra_perms.append(project_pb2.Project.ExtraPerms(
            member_id=user_id, perms=extra_perms))

    return project_dict

  def FetchItems(self, cnxn, keys):
    """On RAM and memcache miss, hit the database to get missing projects."""
    project_rows = self.project_service.project_tbl.Select(
        cnxn, cols=PROJECT_COLS, project_id=keys)
    role_rows = self.project_service.user2project_tbl.Select(
        cnxn, cols=['project_id', 'user_id', 'role_name'],
        project_id=keys)
    extraperm_rows = self.project_service.extraperm_tbl.Select(
        cnxn, cols=EXTRAPERM_COLS, project_id=keys)
    retrieved_dict = self._DeserializeProjects(
        project_rows, role_rows, extraperm_rows)
    return retrieved_dict


class UserToProjectIdTwoLevelCache(caches.AbstractTwoLevelCache):
  """Class to manage both RAM and memcache for project_ids.

  Keys for this cache are int, user_ids, which might correspond to a group.
  This cache should be used to fetch a set of project_ids that the user_id
  is a member of.
  """

  def __init__(self, cachemanager, project_service):
    # type: cachemanager_svc.CacheManager, ProjectService -> None
    super(UserToProjectIdTwoLevelCache, self).__init__(
        cachemanager, 'project_id', 'project_id:', pb_class=None)
    self.project_service = project_service

    # Store the last time the table was fetched for rate limit purposes.
    self.last_fetched = 0

  def FetchItems(self, cnxn, keys):
    # type MonorailConnection, Collection[int] -> Mapping[int, Collection[int]]
    """On RAM and memcache miss, hit the database to get missing user_ids."""

    # Unlike with other caches, we fetch and store the entire table.
    # Thus, for cache misses we limit the rate we re-fetch the table to 60s.
    now = self._GetCurrentTime()
    result_dict = collections.defaultdict(set)

    if (now - self.last_fetched) > 60:
      project_to_user_rows = self.project_service.user2project_tbl.Select(
          cnxn, cols=['project_id', 'user_id'])
      self.last_fetched = now
      # Cache the whole User2Project table.
      for project_id, user_id in project_to_user_rows:
        result_dict[user_id].add(project_id)

    # Assume any requested user missing from result is not in any project.
    result_dict.update(
        (user_id, set()) for user_id in keys if user_id not in result_dict)

    return result_dict

  def _GetCurrentTime(self):
    """ Returns the current time. We made a separate method for this to make it
    easier to unit test. This was a better solution than @mock.patch because
    the test had several unrelated time.time() calls. Modifying those calls
    would be more onerous, having to fix calls for this test.
    """
    return time.time()


class ProjectService(object):
  """The persistence layer for project data."""

  def __init__(self, cache_manager):
    """Initialize this module so that it is ready to use.

    Args:
      cache_manager: local cache with distributed invalidation.
    """
    self.project_tbl = sql.SQLTableManager(PROJECT_TABLE_NAME)
    self.user2project_tbl = sql.SQLTableManager(USER2PROJECT_TABLE_NAME)
    self.extraperm_tbl = sql.SQLTableManager(EXTRAPERM_TABLE_NAME)
    self.membernotes_tbl = sql.SQLTableManager(MEMBERNOTES_TABLE_NAME)
    self.usergroupprojects_tbl = sql.SQLTableManager(
        USERGROUPPROJECTS_TABLE_NAME)
    self.acexclusion_tbl = sql.SQLTableManager(
        AUTOCOMPLETEEXCLUSION_TABLE_NAME)

    # Like a dictionary {project_id: project}
    self.project_2lc = ProjectTwoLevelCache(cache_manager, self)
    # A dictionary of user_id to a set of project ids.
    # Mapping[int, Collection[int]]
    self.user_to_project_2lc = UserToProjectIdTwoLevelCache(cache_manager, self)

    # The project name to ID cache can never be invalidated by individual
    # project changes because it is keyed by strings instead of ints.  In
    # the case of rare operations like deleting a project (or a future
    # project renaming feature), we just InvalidateAll().
    self.project_names_to_ids = caches.RamCache(cache_manager, 'project')

  ### Creating projects

  def CreateProject(
      self, cnxn, project_name, owner_ids, committer_ids, contributor_ids,
      summary, description, state=project_pb2.ProjectState.LIVE,
      access=None, read_only_reason=None, home_page=None, docs_url=None,
      source_url=None, logo_gcs_id=None, logo_file_name=None):
    """Create and store a Project with the given attributes.

    Args:
      cnxn: connection to SQL database.
      project_name: a valid project name, all lower case.
      owner_ids: a list of user IDs for the project owners.
      committer_ids: a list of user IDs for the project members.
      contributor_ids: a list of user IDs for the project contributors.
      summary: one-line explanation of the project.
      description: one-page explanation of the project.
      state: a project state enum defined in project_pb2.
      access: optional project access enum defined in project.proto.
      read_only_reason: if given, provides a status message and marks
        the project as read-only.
      home_page: home page of the project
      docs_url: url to redirect to for wiki/documentation links
      source_url: url to redirect to for source browser links
      logo_gcs_id: google storage object id of the project's logo
      logo_file_name: uploaded file name of the project's logo

    Returns:
      The int project_id of the new project.

    Raises:
      ProjectAlreadyExists: if a project with that name already exists.
    """
    assert project_helpers.IsValidProjectName(project_name)
    if self.LookupProjectIDs(cnxn, [project_name]):
      raise exceptions.ProjectAlreadyExists()

    project = project_pb2.MakeProject(
        project_name, state=state, access=access,
        description=description, summary=summary,
        owner_ids=owner_ids, committer_ids=committer_ids,
        contributor_ids=contributor_ids, read_only_reason=read_only_reason,
        home_page=home_page, docs_url=docs_url, source_url=source_url,
        logo_gcs_id=logo_gcs_id, logo_file_name=logo_file_name)

    project.project_id = self._InsertProject(cnxn, project)
    return project.project_id

  def _InsertProject(self, cnxn, project):
    """Insert the given project into the database."""
    # Note: project_id is not specified because it is auto_increment.
    project_id = self.project_tbl.InsertRow(
        cnxn, project_name=project.project_name,
        summary=project.summary, description=project.description,
        state=str(project.state), access=str(project.access),
        home_page=project.home_page, docs_url=project.docs_url,
        source_url=project.source_url,
        logo_gcs_id=project.logo_gcs_id, logo_file_name=project.logo_file_name)
    logging.info('stored project was given project_id %d', project_id)

    self.user2project_tbl.InsertRows(
        cnxn, ['project_id', 'user_id', 'role_name'],
        [(project_id, user_id, 'owner')
         for user_id in project.owner_ids] +
        [(project_id, user_id, 'committer')
         for user_id in project.committer_ids] +
        [(project_id, user_id, 'contributor')
         for user_id in project.contributor_ids])

    return project_id

  ### Lookup project names and IDs

  def LookupProjectIDs(self, cnxn, project_names):
    """Return a list of project IDs for the specified projects."""
    id_dict, missed_names = self.project_names_to_ids.GetAll(project_names)
    if missed_names:
      rows = self.project_tbl.Select(
          cnxn, cols=['project_name', 'project_id'], project_name=missed_names)
      retrieved_dict = dict(rows)
      self.project_names_to_ids.CacheAll(retrieved_dict)
      id_dict.update(retrieved_dict)

    return id_dict

  def LookupProjectNames(self, cnxn, project_ids):
    """Lookup the names of the projects with the given IDs."""
    projects_dict = self.GetProjects(cnxn, project_ids)
    return {p.project_id: p.project_name
            for p in projects_dict.values()}

  ### Retrieving projects

  def GetAllProjects(self, cnxn, use_cache=True):
    """Return A dict mapping IDs to all live project PBs."""
    project_rows = self.project_tbl.Select(
        cnxn, cols=['project_id'], state=project_pb2.ProjectState.LIVE)
    project_ids = [row[0] for row in project_rows]
    projects_dict = self.GetProjects(cnxn, project_ids, use_cache=use_cache)

    return projects_dict

  def GetVisibleLiveProjects(
      self, cnxn, logged_in_user, effective_ids, domain=None, use_cache=True):
    """Return all user visible live project ids.

    Args:
      cnxn: connection to SQL database.
      logged_in_user: protocol buffer of the logged in user. Can be None.
      effective_ids: set of user IDs for this user. Can be None.
      domain: optional string with HTTP request hostname.
      use_cache: pass False to force database query to find Project protocol
                 buffers.

    Returns:
      A list of project ids of user visible live projects sorted by the names
      of the projects.  If host was provided, only projects with that host
      as their branded domain will be returned.
    """
    project_rows = self.project_tbl.Select(
        cnxn, cols=['project_id'], state=project_pb2.ProjectState.LIVE)
    project_ids = [row[0] for row in project_rows]
    projects_dict = self.GetProjects(cnxn, project_ids, use_cache=use_cache)
    projects_on_host = {
      project_id: project for project_id, project in projects_dict.items()
      if not framework_helpers.GetNeededDomain(project.project_name, domain)}
    visible_projects = []
    for project in projects_on_host.values():
      if permissions.UserCanViewProject(logged_in_user, effective_ids, project):
        visible_projects.append(project)
    visible_projects.sort(key=lambda p: p.project_name)

    return [project.project_id for project in visible_projects]

  def GetProjects(self, cnxn, project_ids, use_cache=True):
    """Load all the Project PBs for the given projects.

    Args:
      cnxn: connection to SQL database.
      project_ids: list of int project IDs
      use_cache: pass False to force database query.

    Returns:
      A dict mapping IDs to the corresponding Project protocol buffers.

    Raises:
      NoSuchProjectException: if any of the projects was not found.
    """
    project_dict, missed_ids = self.project_2lc.GetAll(
        cnxn, project_ids, use_cache=use_cache)

    # Also, update the project name cache.
    self.project_names_to_ids.CacheAll(
        {p.project_name: p.project_id for p in project_dict.values()})

    if missed_ids:
      raise exceptions.NoSuchProjectException()

    return project_dict

  def GetProject(self, cnxn, project_id, use_cache=True):
    """Load the specified project from the database."""
    project_id_dict = self.GetProjects(cnxn, [project_id], use_cache=use_cache)
    return project_id_dict[project_id]

  def GetProjectsByName(self, cnxn, project_names, use_cache=True):
    """Load all the Project PBs for the given projects.

    Args:
      cnxn: connection to SQL database.
      project_names: list of project names.
      use_cache: specifify False to force database query.

    Returns:
      A dict mapping names to the corresponding Project protocol buffers.
    """
    project_ids = list(self.LookupProjectIDs(cnxn, project_names).values())
    projects = self.GetProjects(cnxn, project_ids, use_cache=use_cache)
    return {p.project_name: p for p in projects.values()}

  def GetProjectByName(self, cnxn, project_name, use_cache=True):
    """Load the specified project from the database, None if does not exist."""
    project_dict = self.GetProjectsByName(
        cnxn, [project_name], use_cache=use_cache)
    return project_dict.get(project_name)

  ### Deleting projects

  def ExpungeProject(self, cnxn, project_id):
    """Wipes a project from the system."""
    logging.info('expunging project %r', project_id)
    self.user2project_tbl.Delete(cnxn, project_id=project_id)
    self.usergroupprojects_tbl.Delete(cnxn, project_id=project_id)
    self.extraperm_tbl.Delete(cnxn, project_id=project_id)
    self.membernotes_tbl.Delete(cnxn, project_id=project_id)
    self.acexclusion_tbl.Delete(cnxn, project_id=project_id)
    self.project_tbl.Delete(cnxn, project_id=project_id)

  ### Updating projects

  def UpdateProject(
      self,
      cnxn,
      project_id,
      summary=None,
      description=None,
      state=None,
      state_reason=None,
      access=None,
      issue_notify_address=None,
      attachment_bytes_used=None,
      attachment_quota=None,
      moved_to=None,
      process_inbound_email=None,
      only_owners_remove_restrictions=None,
      read_only_reason=None,
      cached_content_timestamp=None,
      only_owners_see_contributors=None,
      delete_time=None,
      recent_activity=None,
      revision_url_format=None,
      home_page=None,
      docs_url=None,
      source_url=None,
      logo_gcs_id=None,
      logo_file_name=None,
      issue_notify_always_detailed=None,
      commit=True):
    """Update the DB with the given project information."""
    exists = self.project_tbl.SelectValue(
      cnxn, 'project_name', project_id=project_id)
    if not exists:
      raise exceptions.NoSuchProjectException()

    delta = {}
    if summary is not None:
      delta['summary'] = summary
    if description is not None:
      delta['description'] = description
    if state is not None:
      delta['state'] = str(state).lower()
    if state is not None:
      delta['state_reason'] = state_reason
    if access is not None:
      delta['access'] = str(access).lower()
    if read_only_reason is not None:
      delta['read_only_reason'] = read_only_reason
    if issue_notify_address is not None:
      delta['issue_notify_address'] = issue_notify_address
    if attachment_bytes_used is not None:
      delta['attachment_bytes_used'] = attachment_bytes_used
    if attachment_quota is not None:
      delta['attachment_quota'] = attachment_quota
    if moved_to is not None:
      delta['moved_to'] = moved_to
    if process_inbound_email is not None:
      delta['process_inbound_email'] = process_inbound_email
    if only_owners_remove_restrictions is not None:
      delta['only_owners_remove_restrictions'] = (
          only_owners_remove_restrictions)
    if only_owners_see_contributors is not None:
      delta['only_owners_see_contributors'] = only_owners_see_contributors
    if delete_time is not None:
      delta['delete_time'] = delete_time
    if recent_activity is not None:
      delta['recent_activity_timestamp'] = recent_activity
    if revision_url_format is not None:
      delta['revision_url_format'] = revision_url_format
    if home_page is not None:
      delta['home_page'] = home_page
    if docs_url is not None:
      delta['docs_url'] = docs_url
    if source_url is not None:
      delta['source_url'] = source_url
    if logo_gcs_id is not None:
      delta['logo_gcs_id'] = logo_gcs_id
    if logo_file_name is not None:
      delta['logo_file_name'] = logo_file_name
    if issue_notify_always_detailed is not None:
      delta['issue_notify_always_detailed'] = issue_notify_always_detailed
    if cached_content_timestamp is not None:
      delta['cached_content_timestamp'] = cached_content_timestamp
    self.project_tbl.Update(cnxn, delta, project_id=project_id, commit=False)
    self.project_2lc.InvalidateKeys(cnxn, [project_id])
    if commit:
      cnxn.Commit()

  def UpdateCachedContentTimestamp(self, cnxn, project_id, now=None):
    now = now or int(time.time())
    self.project_tbl.Update(
        cnxn, {'cached_content_timestamp': now},
        project_id=project_id, commit=False)
    return now

  def UpdateProjectRoles(
      self, cnxn, project_id, owner_ids, committer_ids, contributor_ids,
      now=None):
    """Store the project's roles in the DB and set cached_content_timestamp."""
    exists = self.project_tbl.SelectValue(
      cnxn, 'project_name', project_id=project_id)
    if not exists:
      raise exceptions.NoSuchProjectException()

    self.UpdateCachedContentTimestamp(cnxn, project_id, now=now)

    self.user2project_tbl.Delete(
        cnxn, project_id=project_id, role_name='owner', commit=False)
    self.user2project_tbl.Delete(
        cnxn, project_id=project_id, role_name='committer', commit=False)
    self.user2project_tbl.Delete(
        cnxn, project_id=project_id, role_name='contributor', commit=False)

    self.user2project_tbl.InsertRows(
        cnxn, ['project_id', 'user_id', 'role_name'],
        [(project_id, user_id, 'owner') for user_id in owner_ids],
        commit=False)
    self.user2project_tbl.InsertRows(
        cnxn, ['project_id', 'user_id', 'role_name'],
        [(project_id, user_id, 'committer')
         for user_id in committer_ids], commit=False)

    self.user2project_tbl.InsertRows(
        cnxn, ['project_id', 'user_id', 'role_name'],
        [(project_id, user_id, 'contributor')
         for user_id in contributor_ids], commit=False)

    cnxn.Commit()
    self.project_2lc.InvalidateKeys(cnxn, [project_id])
    updated_user_ids = owner_ids + committer_ids + contributor_ids
    self.user_to_project_2lc.InvalidateKeys(cnxn, updated_user_ids)

  def MarkProjectDeletable(self, cnxn, project_id, config_service):
    """Update the project's state to make it DELETABLE and free up the name.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the project that will be deleted soon.
      config_service: issue tracker configuration persistence service, needed
          to invalidate cached issue tracker results.
    """
    generated_name = 'DELETABLE_%d' % project_id
    delta = {'project_name': generated_name, 'state': 'deletable'}
    self.project_tbl.Update(cnxn, delta, project_id=project_id)

    self.project_2lc.InvalidateKeys(cnxn, [project_id])
    # We cannot invalidate a specific part of the name->proj cache by name,
    # So, tell every job to just drop the whole cache.  It should refill
    # efficiently and incrementally from memcache.
    self.project_2lc.InvalidateAllRamEntries(cnxn)
    self.user_to_project_2lc.InvalidateAllRamEntries(cnxn)
    config_service.InvalidateMemcacheForEntireProject(project_id)

  def UpdateRecentActivity(self, cnxn, project_id, now=None):
    """Set the project's recent_activity to the current time."""
    now = now or int(time.time())
    project = self.GetProject(cnxn, project_id)
    if now > project.recent_activity + RECENT_ACTIVITY_THRESHOLD:
      self.UpdateProject(cnxn, project_id, recent_activity=now)

  ### Roles, memberships, and extra perms

  def GetUserRolesInAllProjects(self, cnxn, effective_ids):
    """Return three sets of project IDs where the user has a role."""
    owned_project_ids = set()
    membered_project_ids = set()
    contrib_project_ids = set()

    rows = []
    if effective_ids:
      rows = self.user2project_tbl.Select(
          cnxn, cols=['project_id', 'role_name'], user_id=effective_ids)

    for project_id, role_name in rows:
      if role_name == 'owner':
        owned_project_ids.add(project_id)
      elif role_name == 'committer':
        membered_project_ids.add(project_id)
      elif role_name == 'contributor':
        contrib_project_ids.add(project_id)
      else:
        logging.warn('Unexpected role name %r', role_name)

    return owned_project_ids, membered_project_ids, contrib_project_ids

  def GetProjectMemberships(self, cnxn, effective_ids, use_cache=True):
    # type: MonorailConnection, Collection[int], Optional[bool] ->
    #     Mapping[int, Collection[int]]
    """Return a list of project IDs where the user has a membership."""
    project_id_dict, missed_ids = self.user_to_project_2lc.GetAll(
        cnxn, effective_ids, use_cache=use_cache)

    # Users that were missed are assumed to not have any projects.
    assert not missed_ids

    return project_id_dict

  def UpdateExtraPerms(
      self, cnxn, project_id, member_id, extra_perms, now=None):
    """Load the project, update the member's extra perms, and store.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.
      member_id: int user id of the user that was edited.
      extra_perms: list of strings for perms that the member
          should have over-and-above what their role gives them.
      now: fake int(time.time()) value passed in during unit testing.
    """
    # This will be a newly constructed object, not from the cache and not
    # shared with any other thread.
    project = self.GetProject(cnxn, project_id, use_cache=False)

    idx, member_extra_perms = permissions.FindExtraPerms(project, member_id)
    if not member_extra_perms and not extra_perms:
      return
    if member_extra_perms and list(member_extra_perms.perms) == extra_perms:
      return
    # Either project is None or member_id is not a member of the project.
    if idx is None:
      return

    if member_extra_perms:
      member_extra_perms.perms = extra_perms
    else:
      member_extra_perms = project_pb2.Project.ExtraPerms(
          member_id=member_id, perms=extra_perms)
      # Keep the list of extra_perms sorted by member id.
      project.extra_perms.insert(idx, member_extra_perms)

    self.extraperm_tbl.Delete(
        cnxn, project_id=project_id, user_id=member_id, commit=False)
    self.extraperm_tbl.InsertRows(
        cnxn, EXTRAPERM_COLS,
        [(project_id, member_id, perm) for perm in extra_perms],
        commit=False)
    project.cached_content_timestamp = self.UpdateCachedContentTimestamp(
        cnxn, project_id, now=now)
    cnxn.Commit()

    self.project_2lc.InvalidateKeys(cnxn, [project_id])

  ### Project Commitments

  def GetProjectCommitments(self, cnxn, project_id):
    """Get the project commitments (notes) from the DB.

    Args:
      cnxn: connection to SQL database.
      project_id: int project ID.

    Returns:
      A the specified project's ProjectCommitments instance, or an empty one,
        if the project doesn't exist, or has not documented member
        commitments.
    """
    # Get the notes.  Don't get the project_id column
    # since we already know that value.
    notes_rows = self.membernotes_tbl.Select(
        cnxn, cols=['user_id', 'notes'], project_id=project_id)
    notes_dict = dict(notes_rows)

    project_commitments = project_pb2.ProjectCommitments()
    project_commitments.project_id = project_id
    for user_id in notes_dict.keys():
      commitment = project_pb2.ProjectCommitments.MemberCommitment(
          member_id=user_id,
          notes=notes_dict.get(user_id, ''))
      project_commitments.commitments.append(commitment)

    return project_commitments

  def _StoreProjectCommitments(self, cnxn, project_commitments):
    """Store an updated set of project commitments in the DB.

    Args:
      cnxn: connection to SQL database.
      project_commitments: ProjectCommitments PB
    """
    project_id = project_commitments.project_id
    notes_rows = []
    for commitment in project_commitments.commitments:
      notes_rows.append(
          (project_id, commitment.member_id, commitment.notes))

    # TODO(jrobbins): this should be in a transaction.
    self.membernotes_tbl.Delete(cnxn, project_id=project_id)
    self.membernotes_tbl.InsertRows(
        cnxn, MEMBERNOTES_COLS, notes_rows, ignore=True)

  def UpdateCommitments(self, cnxn, project_id, member_id, notes):
    """Update the member's commitments in the specified project.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.
      member_id: int user ID of the user that was edited.
      notes: further notes on the member's expected involvment
        in the project.
    """
    project_commitments = self.GetProjectCommitments(cnxn, project_id)

    commitment = None
    for c in project_commitments.commitments:
      if c.member_id == member_id:
        commitment = c
        break
    else:
      commitment = project_pb2.ProjectCommitments.MemberCommitment(
          member_id=member_id)
      project_commitments.commitments.append(commitment)

    dirty = False

    if commitment.notes != notes:
      commitment.notes = notes
      dirty = True

    if dirty:
      self._StoreProjectCommitments(cnxn, project_commitments)

  def GetProjectAutocompleteExclusion(self, cnxn, project_id):
    """Get user ids who are excluded from autocomplete list.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.

    Returns:
      A pair containing: a list of user IDs who are excluded from the
      autocomplete list for given project, and a list of group IDs to
      not expand.
    """
    ac_exclusion_rows = self.acexclusion_tbl.Select(
        cnxn, cols=['user_id'], project_id=project_id, ac_exclude=True)
    ac_exclusion_ids = [row[0] for row in ac_exclusion_rows]
    no_expand_rows = self.acexclusion_tbl.Select(
        cnxn, cols=['user_id'], project_id=project_id, no_expand=True)
    no_expand_ids = [row[0] for row in no_expand_rows]
    return ac_exclusion_ids, no_expand_ids

  def UpdateProjectAutocompleteExclusion(
      self, cnxn, project_id, member_id, ac_exclude, no_expand):
    """Update autocomplete exclusion for given user.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.
      member_id: int user ID of the user that was edited.
      ac_exclude: Whether this user should be excluded.
      no_expand: Whether this group should not be expanded.
    """
    if ac_exclude or no_expand:
      self.acexclusion_tbl.InsertRows(
        cnxn, AUTOCOMPLETEEXCLUSION_COLS,
        [(project_id, member_id, ac_exclude, no_expand)],
        replace=True)
    else:
      self.acexclusion_tbl.Delete(
          cnxn, project_id=project_id, user_id=member_id)

    self.UpdateCachedContentTimestamp(cnxn, project_id)
    cnxn.Commit()

    self.project_2lc.InvalidateKeys(cnxn, [project_id])

  def ExpungeUsersInProjects(self, cnxn, user_ids, limit=None):
    """Wipes the given users from the projects system.

    This method will not commit the operation. This method will
    not make changes to in-memory data.
    """
    self.extraperm_tbl.Delete(cnxn, user_id=user_ids, limit=limit, commit=False)
    self.acexclusion_tbl.Delete(
        cnxn, user_id=user_ids, limit=limit, commit=False)
    self.membernotes_tbl.Delete(
        cnxn, user_id=user_ids, limit=limit, commit=False)
    self.user2project_tbl.Delete(
        cnxn, user_id=user_ids, limit=limit, commit=False)
