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

"""Implements processing of issue update command lines.

This currently processes the leading command-lines that appear
at the top of inbound email messages to update existing issues.

It could also be expanded to allow new issues to be created. Or, to
handle commands in commit-log messages if the version control system
invokes a webhook.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import re

from businesslogic import work_env
from features import commands
from features import send_notifications
from framework import emailfmt
from framework import exceptions
from framework import framework_bizobj
from framework import framework_helpers
from framework import permissions
from mrproto import tracker_pb2


# Actions have separate 'Parse' and 'Run' implementations to allow better
# testing coverage.
class IssueAction(object):
  """Base class for all issue commands."""

  def __init__(self):
    self.parser = commands.AssignmentParser(None)
    self.description = ''
    self.inbound_message = None
    self.commenter_id = None
    self.project = None
    self.config = None
    self.hostport = framework_helpers.GetHostPort()

  def Parse(
      self, cnxn, project_name, commenter_id, lines, services,
      strip_quoted_lines=False, hostport=None):
    """Populate object from raw user input.

    Args:
      cnxn: connection to SQL database.
      project_name: Name of the project containing the issue.
      commenter_id: int user ID of user creating comment.
      lines: list of strings containing test to be parsed.
      services: References to existing objects from Monorail's service layer.
      strip_quoted_lines: boolean for whether to remove quoted lines from text.
      hostport: Optionally override the current instance's hostport variable.

    Returns:
      A boolean for whether any command lines were found while parsing.

    Side-effect:
      Edits the values of instance variables in this class with parsing output.
    """
    self.project = services.project.GetProjectByName(cnxn, project_name)
    self.config = services.config.GetProjectConfig(
        cnxn, self.project.project_id)
    self.commenter_id = commenter_id

    has_commands = False

    # Process all valid key-value lines. Once we find a non key-value line,
    # treat the rest as the 'description'.
    for idx, line in enumerate(lines):
      valid_line = False
      m = re.match(r'^\s*(\w+)\s*\:\s*(.*?)\s*$', line)
      if m:
        has_commands = True
        # Process Key-Value
        key = m.group(1).lower()
        value = m.group(2)
        valid_line = self.parser.ParseAssignment(
            cnxn, key, value, self.config, services, self.commenter_id)

      if not valid_line:
        # Not Key-Value. Treat this line and remaining as 'description'.
        # First strip off any trailing blank lines.
        while lines and not lines[-1].strip():
          lines.pop()
        if lines:
          self.description = '\n'.join(lines[idx:])
          break

    if strip_quoted_lines:
      self.inbound_message = '\n'.join(lines)
      self.description = emailfmt.StripQuotedText(self.description)

    if hostport:
      self.hostport = hostport

    for key in ['owner_id', 'cc_add', 'cc_remove', 'summary',
                'status', 'labels_add', 'labels_remove', 'branch']:
      logging.info('\t%s: %s', key, self.parser.__dict__[key])

    for key in ['commenter_id', 'description', 'hostport']:
      logging.info('\t%s: %s', key, self.__dict__[key])

    return has_commands

  def Run(self, mc, services):
    """Execute this action."""
    raise NotImplementedError()


class UpdateIssueAction(IssueAction):
  """Implements processing email replies or the "update issue" command."""

  def __init__(self, local_id):
    super(UpdateIssueAction, self).__init__()
    self.local_id = local_id

  def Run(self, mc, services):
    """Updates an issue based on the parsed commands."""
    try:
      issue = services.issue.GetIssueByLocalID(
          mc.cnxn, self.project.project_id, self.local_id, use_cache=False)
    except exceptions.NoSuchIssueException:
      return  # Issue does not exist, so do nothing

    delta = tracker_pb2.IssueDelta()

    allow_edit = permissions.CanEditIssue(
        mc.auth.effective_ids, mc.perms, self.project, issue)

    if allow_edit:
      delta.summary = self.parser.summary or issue.summary
      if self.parser.status is None:
        delta.status = issue.status
      else:
        delta.status = self.parser.status

      if self.parser.owner_id is None:
        delta.owner_id = issue.owner_id
      else:
        delta.owner_id = self.parser.owner_id

      delta.cc_ids_add = list(self.parser.cc_add)
      delta.cc_ids_remove = list(self.parser.cc_remove)
      delta.labels_add = self.parser.labels_add
      delta.labels_remove = self.parser.labels_remove
      # TODO(jrobbins): allow editing of custom fields

    with work_env.WorkEnv(mc, services) as we:
      we.UpdateIssue(
          issue, delta, self.description, inbound_message=self.inbound_message)

    logging.info('Updated issue %s:%s',
                 self.project.project_name, issue.local_id)

    # Note: notifications are generated in work_env.
