# 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

import re

from api import resource_name_converters as rnc
from api.v3 import api_constants
from api.v3 import converters
from api.v3 import monorail_servicer
from api.v3 import paginator
from api.v3.api_proto import issues_pb2
from api.v3.api_proto import issue_objects_pb2
from api.v3.api_proto import issues_prpc_pb2
from businesslogic import work_env
from framework import exceptions

# We accept only the following filter, and only on ListComments.
# If we accept more complex filters in the future, introduce a library.
_APPROVAL_DEF_FILTER_RE = re.compile(
    r'approval = "(?P<approval_name>%s)"$' % rnc.APPROVAL_DEF_NAME_PATTERN)


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

  DESCRIPTION = issues_prpc_pb2.IssuesServiceDescription

  @monorail_servicer.PRPCMethod
  def GetIssue(self, mc, request):
    # type: (MonorailContext, GetIssueRequest) -> Issue
    """pRPC API method that implements GetIssue.

    Raises:
      InputException: the given name does not have a valid format.
      NoSuchIssueException: the issue is not found.
      PermissionException the user is not allowed to view the issue.
    """
    issue_id = rnc.IngestIssueName(mc.cnxn, request.name, self.services)
    with work_env.WorkEnv(mc, self.services) as we:
      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.name))
      mc.LookupLoggedInUserPerms(project)
      issue = we.GetIssue(issue_id, allow_viewing_deleted=True)
      migrated_id = we.GetIssueMigratedID(
          project.project_name, issue.local_id, issue.labels)
    return self.converter.ConvertIssue(issue, migrated_id)

  @monorail_servicer.PRPCMethod
  def BatchGetIssues(self, mc, request):
    # type: (MonorailContext, BatchGetIssuesRequest) -> BatchGetIssuesResponse
    """pRPC API method that implements BatchGetIssues.

    Raises:
      InputException: If `names` is formatted incorrectly. Or if a parent
          collection in `names` does not match the value in `parent`.
      NoSuchIssueException: If any of the given issues do not exist.
      PermissionException If the requester does not have permission to view one
          (or more) of the given issues.
    """
    if len(request.names) > api_constants.MAX_BATCH_ISSUES:
      raise exceptions.InputException(
          'Requesting %d issues when the allowed maximum is %d issues.' %
          (len(request.names), api_constants.MAX_BATCH_ISSUES))
    if request.parent:
      parent_match = rnc._GetResourceNameMatch(
          request.parent, rnc.PROJECT_NAME_RE)
      parent_project = parent_match.group('project_name')
      with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
        for name in request.names:
          try:
            name_match = rnc._GetResourceNameMatch(name, rnc.ISSUE_NAME_RE)
            issue_project = name_match.group('project')
            if issue_project != parent_project:
              err_agg.AddErrorMessage(
                  '%s is not a child issue of %s.' % (name, request.parent))
          except exceptions.InputException as e:
            err_agg.AddErrorMessage(str(e))
    with work_env.WorkEnv(mc, self.services) as we:
      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
      # all servicer methods that are scoped to a single Project need to call
      # mc.LookupLoggedInUserPerms.
      #  This method does not because it may be scoped to multiple projects.
      issue_ids = rnc.IngestIssueNames(mc.cnxn, request.names, self.services)
      issues_by_iid = we.GetIssuesDict(issue_ids)
    return issues_pb2.BatchGetIssuesResponse(
        issues=self.converter.ConvertIssues(
            [issues_by_iid[issue_id] for issue_id in issue_ids]))

  @monorail_servicer.PRPCMethod
  def SearchIssues(self, mc, request):
    # type: (MonorailContext, SearchIssuesRequest) -> SearchIssuesResponse
    """pRPC API method that implements SearchIssue.

    Raises:
      InputException: if any given names in `projects` are invalid or if the
        search query uses invalid syntax (ie: unmatched parentheses).
    """
    page_size = paginator.CoercePageSize(
        request.page_size, api_constants.MAX_ISSUES_PER_PAGE)
    pager = paginator.Paginator(
        page_size=page_size,
        order_by=request.order_by,
        query=request.query,
        projects=request.projects)

    project_names = []
    for resource_name in request.projects:
      match = rnc._GetResourceNameMatch(resource_name, rnc.PROJECT_NAME_RE)
      project_names.append(match.group('project_name'))

    with work_env.WorkEnv(mc, self.services) as we:
      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
      # all servicer methods that are scoped to a single Project need to call
      # mc.LookupLoggedInUserPerms.
      #  This method does not because it may be scoped to multiple projects.
      list_result = we.SearchIssues(
          request.query, project_names, mc.auth.user_id, page_size,
          pager.GetStart(request.page_token), request.order_by)

    return issues_pb2.SearchIssuesResponse(
        issues=self.converter.ConvertIssues(list_result.items),
        next_page_token=pager.GenerateNextPageToken(list_result.next_start))

  @monorail_servicer.PRPCMethod
  def ListComments(self, mc, request):
    # type: (MonorailContext, ListCommentsRequest) -> ListCommentsResponse
    """pRPC API method that implements ListComments.

    Raises:
      InputException: the given name format or page_size are not valid.
      NoSuchIssueException: the parent is not found.
      PermissionException: the user is not allowed to view the parent.
    """
    issue_id = rnc.IngestIssueName(mc.cnxn, request.parent, self.services)
    page_size = paginator.CoercePageSize(
        request.page_size, api_constants.MAX_COMMENTS_PER_PAGE)
    pager = paginator.Paginator(
      parent=request.parent, page_size=page_size, filter_str=request.filter)
    approval_id = None
    if request.filter:
      match = _APPROVAL_DEF_FILTER_RE.match(request.filter)
      if match:
        approval_id = rnc.IngestApprovalDefName(
            mc.cnxn, match.group('approval_name'), self.services)
      if not match:
        raise exceptions.InputException(
            'Filtering other than approval not supported.')

    with work_env.WorkEnv(mc, self.services) as we:
      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.parent))
      mc.LookupLoggedInUserPerms(project)
      list_result = we.SafeListIssueComments(
          issue_id, page_size, pager.GetStart(request.page_token),
          approval_id=approval_id)
    return issues_pb2.ListCommentsResponse(
        comments=self.converter.ConvertComments(issue_id, list_result.items),
        next_page_token=pager.GenerateNextPageToken(list_result.next_start))

  @monorail_servicer.PRPCMethod
  def ListApprovalValues(self, mc, request):
    # type: (MonorailContext, ListApprovalValuesRequest) ->
    #     ListApprovalValuesResponse
    """pRPC API method that implements ListApprovalValues.

    Raises:
      InputException: the given parent does not have a valid format.
      NoSuchIssueException: the parent issue is not found.
      PermissionException the user is not allowed to view the parent issue.
    """
    issue_id = rnc.IngestIssueName(mc.cnxn, request.parent, self.services)
    with work_env.WorkEnv(mc, self.services) as we:
      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
      project = we.GetProjectByName(rnc.IngestProjectFromIssue(request.parent))
      mc.LookupLoggedInUserPerms(project)
      issue = we.GetIssue(issue_id)

    api_avs = self.converter.ConvertApprovalValues(issue.approval_values,
        issue.field_values, issue.phases, issue_id=issue_id)

    return issues_pb2.ListApprovalValuesResponse(approval_values=api_avs)

  @monorail_servicer.PRPCMethod
  def MakeIssueFromTemplate(self, _mc, _request):
    # type: (MonorailContext, MakeIssueFromTemplateRequest) -> Issue
    """pRPC API method that implements MakeIssueFromTemplate.

    Raises:
      TODO(crbug/monorail/7197): Document errors when implemented
    """
    # Phase 1: Gather info
    #   Get project id and template name from template resource name.
    #   Get template pb.
    #   Make tracker_pb2.IssueDelta from request.template_issue_delta, share
    #   code with v3/ModifyIssue

    # with work_env.WorkEnv(mc, self.services) as we:
    #   project = ... get project from template.
    #   mc.LookupLoggedInUserPerms(project)
    #   created_issue = we.MakeIssueFromTemplate(template, description, delta)

    # Return newly created API issue.
    # return converters.ConvertIssue(created_issue)

    return issue_objects_pb2.Issue()

  @monorail_servicer.PRPCMethod
  def MakeIssue(self, mc, request):
    # type: (MonorailContext, MakeIssueRequest) -> Issue
    """pRPC API method that implements MakeIssue.

    Raises:
      InputException if any given names do not have a valid format or if any
        fields in the requested issue were invalid.
      NoSuchProjectException if no project exists with the given parent.
      FilterRuleException if proposed issue values violate any filter rules
        that shows error.
      PermissionException if user lacks sufficient permissions.
    """
    project_id = rnc.IngestProjectName(mc.cnxn, request.parent, self.services)
    with work_env.WorkEnv(mc, self.services) as we:
      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
      project = we.GetProject(project_id)
      mc.LookupLoggedInUserPerms(project)

    ingested_issue = self.converter.IngestIssue(
        request.issue, project_id)
    send_email = self.converter.IngestNotifyType(request.notify_type)
    ingested_attachments = self.converter.IngestAttachmentUploads(
      request.uploads)
    with work_env.WorkEnv(mc, self.services) as we:
      created_issue = we.MakeIssue(
          ingested_issue,
          request.description,
          send_email,
          attachment_uploads=ingested_attachments)
      starred_issue = we.StarIssue(created_issue, True)

    return self.converter.ConvertIssue(starred_issue)

  @monorail_servicer.PRPCMethod
  def ModifyIssues(self, mc, request):
    # type: (MonorailContext, ModifyIssuesRequest) -> ModifyIssuesResponse
    """pRPC API method that implements ModifyIssues.

    Raises:
      InputException if any given names do not have a valid format or if any
        fields in the requested issue were invalid.
      NoSuchIssueException if some issues weren't found.
      NoSuchProjectException if no project was found for some given issues.
      FilterRuleException if proposed issue changes violate any filter rules
        that shows error.
      PermissionException if user lacks sufficient permissions.
    """
    if not request.deltas:
      return issues_pb2.ModifyIssuesResponse()
    if len(request.deltas) > api_constants.MAX_MODIFY_ISSUES:
      raise exceptions.InputException(
          'Requesting %d updates when the allowed maximum is %d updates.' %
          (len(request.deltas), api_constants.MAX_MODIFY_ISSUES))
    impacted_issues_count = 0
    for delta in request.deltas:
      impacted_issues_count += (
          len(delta.blocked_on_issues_remove) +
          len(delta.blocking_issues_remove) +
          len(delta.issue.blocking_issue_refs) +
          len(delta.issue.blocked_on_issue_refs))
      if 'merged_into_issue_ref' in delta.update_mask.paths:
        impacted_issues_count += 1
    if impacted_issues_count > api_constants.MAX_MODIFY_IMPACTED_ISSUES:
      raise exceptions.InputException(
          'Updates include %d impacted issues when the allowed maximum is %d.' %
          (impacted_issues_count, api_constants.MAX_MODIFY_IMPACTED_ISSUES))
    iid_delta_pairs = self.converter.IngestIssueDeltas(request.deltas)
    with work_env.WorkEnv(mc, self.services) as we:
      issues = we.ModifyIssues(
          iid_delta_pairs,
          attachment_uploads=self.converter.IngestAttachmentUploads(
              request.uploads),
          comment_content=request.comment_content,
          send_email=self.converter.IngestNotifyType(request.notify_type))

    return issues_pb2.ModifyIssuesResponse(
        issues=self.converter.ConvertIssues(issues))

  @monorail_servicer.PRPCMethod
  def ModifyIssueApprovalValues(self, mc, request):
    # type: (MonorailContext, ModifyIssueApprovalValuesRequest) ->
    #     ModifyIssueApprovalValuesResponse
    """pRPC API method that implements ModifyIssueApprovalValues.

    Raises:
      InputException if any fields in the delta were invalid.
      NoSuchIssueException: if the issue of any ApprovalValue isn't found.
      NoSuchProjectException: if the parent project of any ApprovalValue isn't
          found.
      NoSuchUserException: if any user value provided isn't found.
      PermissionException if user lacks sufficient permissions.
      # TODO(crbug/monorail/7925): Not all of these are yet thrown.
    """
    if len(request.deltas) > api_constants.MAX_MODIFY_APPROVAL_VALUES:
      raise exceptions.InputException(
          'Requesting %d updates when the allowed maximum is %d updates.' %
          (len(request.deltas), api_constants.MAX_MODIFY_APPROVAL_VALUES))
    response = issues_pb2.ModifyIssueApprovalValuesResponse()
    delta_specifications = self.converter.IngestApprovalDeltas(
        request.deltas, mc.auth.user_id)
    send_email = self.converter.IngestNotifyType(request.notify_type)
    with work_env.WorkEnv(mc, self.services) as we:
      # NOTE(crbug/monorail/7614): Until the referenced cleanup is complete,
      # all servicer methods that are scoped to a single Project need to call
      # mc.LookupLoggedInUserPerms.
      # This method does not because it may be scoped to multiple projects.
      issue_approval_values = we.BulkUpdateIssueApprovalsV3(
          delta_specifications, request.comment_content, send_email=send_email)
    api_avs = []
    for issue, approval_value in issue_approval_values:
      api_avs.extend(
          self.converter.ConvertApprovalValues(
              [approval_value],
              issue.field_values,
              issue.phases,
              issue_id=issue.issue_id))
    response.approval_values.extend(api_avs)
    return response

  @monorail_servicer.PRPCMethod
  def ModifyCommentState(self, mc, request):
    # type: (MonorailContext, ModifyCommentStateRequest) ->
    #     ModifyCommentStateResponse
    """pRPC API method that implements ModifyCommentState.

    We do not support changing between DELETED <-> SPAM. User must
    undelete or unflag-as-spam first.

    Raises:
      NoSuchProjectException if the parent Project does not exist.
      NoSuchIssueException: if the issue does not exist.
      NoSuchCommentException: if the comment does not exist.
      PermissionException if user lacks sufficient permissions.
      ActionNotSupported if user requests unsupported state transitions.
    """
    (project_id, issue_id,
     comment_num) = rnc.IngestCommentName(mc.cnxn, request.name, self.services)
    with work_env.WorkEnv(mc, self.services) as we:
      # TODO(crbug/monorail/7614): Eliminate the need to do this lookup.
      project = we.GetProject(project_id)
      mc.LookupLoggedInUserPerms(project)
      issue = we.GetIssue(issue_id, use_cache=False)
      comments_list = we.SafeListIssueComments(issue_id, 1, comment_num).items
      try:
        comment = comments_list[0]
      except IndexError:
        raise exceptions.NoSuchCommentException()

      if request.state == issue_objects_pb2.IssueContentState.Value('ACTIVE'):
        if comment.is_spam:
          we.FlagComment(issue, comment, False)
        elif comment.deleted_by != 0:
          we.DeleteComment(issue, comment, delete=False)
        else:
          # No-op if already currently active
          pass
      elif request.state == issue_objects_pb2.IssueContentState.Value(
          'DELETED'):
        if (not comment.deleted_by) and (not comment.is_spam):
          we.DeleteComment(issue, comment, delete=True)
        elif comment.deleted_by and not comment.is_spam:
          # No-op if already deleted
          pass
        else:
          raise exceptions.ActionNotSupported(
              'Cannot change comment state from spam to deleted.')
      elif request.state == issue_objects_pb2.IssueContentState.Value('SPAM'):
        if (not comment.deleted_by) and (not comment.is_spam):
          we.FlagComment(issue, comment, True)
        elif comment.is_spam:
          # No-op if already spam
          pass
        else:
          raise exceptions.ActionNotSupported(
              'Cannot change comment state from deleted to spam.')
      else:
        raise exceptions.ActionNotSupported('Unsupported target comment state.')

      # FlagComment does not have side effect on comment, must refresh.
      refreshed_comment = we.SafeListIssueComments(issue_id, 1,
                                                   comment_num).items[0]

    converted_comment = self.converter.ConvertComments(
        issue_id, [refreshed_comment])[0]
    return issues_pb2.ModifyCommentStateResponse(comment=converted_comment)
