# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

from google.protobuf import empty_pb2

from api import resource_name_converters as rnc
from api.v3 import monorail_servicer
from api.v3 import api_constants
from api.v3.api_proto import users_pb2
from api.v3.api_proto import user_objects_pb2
from api.v3.api_proto import users_prpc_pb2
from businesslogic import work_env
from framework import exceptions


class UsersServicer(monorail_servicer.MonorailServicer):
  """Handle API requests related to User objects.
  Each API request is implemented with a method as defined in the
  .proto file. Each method does any request-specific validation, uses work_env
  to safely operate on business objects, and returns a response proto.
  """

  DESCRIPTION = users_prpc_pb2.UsersServiceDescription

  @monorail_servicer.PRPCMethod
  def GetUser(self, mc, request):
    # type: (MonorailContext, GetUserRequest) ->
    # GetUserResponse
    """pRPC API method that implements GetUser.

      Raises:
        InputException if a name in request.name is invalid.
        NoSuchUserException if a User is not found.
    """
    user_id = rnc.IngestUserName(mc.cnxn, request.name, self.services)

    with work_env.WorkEnv(mc, self.services) as we:
      user = we.GetUser(user_id)

    return self.converter.ConvertUser(user)

  @monorail_servicer.PRPCMethod
  def BatchGetUsers(self, mc, request):
    # type: (MonorailContext, BatchGetUsersRequest) ->
    # BatchGetUsersResponse
    """pRPC API method that implements BatchGetUsers.

      Raises:
        InputException if a name in request.names is invalid.
        NoSuchUserException if a User is not found.
    """
    if len(request.names) > api_constants.MAX_BATCH_USERS:
      raise exceptions.InputException(
          'Requesting %d users when the allowed maximum is %d users.' %
          (len(request.names), api_constants.MAX_BATCH_USERS))
    user_ids = rnc.IngestUserNames(mc.cnxn, request.names, self.services)

    with work_env.WorkEnv(mc, self.services) as we:
      users = we.BatchGetUsers(user_ids)

    api_users_by_id = self.converter.ConvertUsers(
        [user.user_id for user in users])
    api_users = [api_users_by_id[user_id] for user_id in user_ids]

    return users_pb2.BatchGetUsersResponse(users=api_users)

  @monorail_servicer.PRPCMethod
  def StarProject(self, mc, request):
    # type: (MonorailContext, StarProjectRequest) ->
    # ProjectStar
    """pRPC API method that implements StarProject.

      Raises:
        InputException if the project name in request.project is invalid.
        NoSuchProjectException if no project exists with the given name.
    """
    project_id = rnc.IngestProjectName(mc.cnxn, request.project, self.services)

    with work_env.WorkEnv(mc, self.services) as we:
      we.StarProject(project_id, True)

    user_id = mc.auth.user_id
    star_name = rnc.ConvertProjectStarName(
        mc.cnxn, user_id, project_id, self.services)

    return user_objects_pb2.ProjectStar(name=star_name)

  @monorail_servicer.PRPCMethod
  def UnStarProject(self, mc, request):
    # type: (MonorailContext, UnStarProjectRequest) ->
    # Empty
    """pRPC API method that implements UnStarProject.

      Raises:
        InputException if the project name in request.project is invalid.
        NoSuchProjectException if no project exists with the given name.
    """
    project_id = rnc.IngestProjectName(mc.cnxn, request.project, self.services)

    with work_env.WorkEnv(mc, self.services) as we:
      we.StarProject(project_id, False)

    return empty_pb2.Empty()

  @monorail_servicer.PRPCMethod
  def ListProjectStars(self, mc, request):
    # type: (MonorailContext, ListProjectStarsRequest) ->
    #   ListProjectStarsResponse
    """pRPC API method that implements ListProjectStars.

      Raises:
        InputException: if the `page_token` or `parent` is invalid.
        NoSuchUserException: if the User is not found.
    """
    user_id = rnc.IngestUserName(mc.cnxn, request.parent, self.services)

    with work_env.WorkEnv(mc, self.services) as we:
      projects = we.ListStarredProjects(user_id)

    # TODO(crbug.com/monorail/7175): Add pagination logic.
    return users_pb2.ListProjectStarsResponse(
        project_stars=self.converter.ConvertProjectStars(user_id, projects))
