# Copyright 2019 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

"""Handlers to process alert notification messages."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import itertools
import logging
import email.utils

import settings
from businesslogic import work_env
from features import commitlogcommands
from framework import framework_constants
from framework import monorailcontext
from framework import emailfmt
from tracker import tracker_constants
from tracker import tracker_helpers

AlertEmailHeader = emailfmt.AlertEmailHeader


def IsAllowlisted(email_addr):
  """Returns whether a given email is from one of the allowlisted domains."""
  return email_addr.endswith(settings.alert_allowlisted_suffixes)


def IsCommentSizeReasonable(comment):
  # type: str -> bool
  """Returns whether a given comment string is a reasonable size."""
  return len(comment) <= tracker_constants.MAX_COMMENT_CHARS


def FindAlertIssue(services, cnxn, project_id, incident_label):
  """Find the existing issue with the incident_label."""
  if not incident_label:
    return None

  label_id = services.config.LookupLabelID(
      cnxn, project_id, incident_label)
  if not label_id:
    return None

  # If a new notification is sent with an existing incident ID, then it
  # should be added as a new comment into the existing issue.
  #
  # If there are more than one issues with a given incident ID, then
  # it's either
  # - there is a bug in this module,
  # - the issues were manually updated with the same incident ID, OR
  # - an issue auto update program updated the issues with the same
  #  incident ID, which also sounds like a bug.
  #
  # In any cases, the latest issue should be used, whichever status it has.
  # - The issue of an ongoing incident can be mistakenly closed by
  # engineers.
  # - A closed incident can be reopened, and, therefore, the issue also
  # needs to be re-opened.
  issue_ids = services.issue.GetIIDsByLabelIDs(
      cnxn, [label_id], project_id, None)
  issues = services.issue.GetIssues(cnxn, issue_ids)
  if issues:
    return max(issues, key=lambda issue: issue.modified_timestamp)
  return None


def GetAlertProperties(services, cnxn, project_id, incident_id, trooper_queue,
                       msg):
  """Create a dict of issue property values for the alert to be created with.

  Args:
    cnxn: connection to SQL database.
    project_id: the ID of the Monorail project, in which the alert should
      be created in.
    incident_id: string containing an optional unique incident used to
      de-dupe alert issues.
    trooper_queue: the label specifying the trooper queue to add an issue into.
    msg: the email.Message object containing the alert notification.

  Returns:
    A dict of issue property values to be used for issue creation.
  """
  proj_config = services.config.GetProjectConfig(cnxn, project_id)
  user_svc = services.user
  known_labels = set(wkl.label.lower() for wkl in proj_config.well_known_labels)

  props = dict(
      owner_id=_GetOwnerID(user_svc, cnxn, msg.get(AlertEmailHeader.OWNER)),
      cc_ids=_GetCCIDs(user_svc, cnxn, msg.get(AlertEmailHeader.CC)),
      component_ids=_GetComponentIDs(
          proj_config, msg.get(AlertEmailHeader.COMPONENT)),

      # Props that are added as labels.
      trooper_queue=(trooper_queue or 'Infra-Troopers-Alerts'),
      incident_label=_GetIncidentLabel(incident_id),
      priority=_GetPriority(known_labels, msg.get(AlertEmailHeader.PRIORITY)),
      oses=_GetOSes(known_labels, msg.get(AlertEmailHeader.OS)),
      issue_type=_GetIssueType(known_labels, msg.get(AlertEmailHeader.TYPE)),

      field_values=[],
  )

  # Props that depend on other props.
  props.update(
      status=_GetStatus(proj_config, props['owner_id'],
                        msg.get(AlertEmailHeader.STATUS)),
      labels=_GetLabels(msg.get(AlertEmailHeader.LABEL),
                        props['trooper_queue'], props['incident_label'],
                        props['priority'], props['issue_type'], props['oses']),
  )

  return props


def ProcessEmailNotification(
    services, cnxn, project, project_addr, from_addr, auth, subject, body,
    incident_id, msg, trooper_queue=None):
  # type: (...) -> None
  """Process an alert notification email to create or update issues.""

  Args:
    cnxn: connection to SQL database.
    project: Project PB for the project containing the issue.
    project_addr: string email address the alert email was sent to.
    from_addr: string email address of the user who sent the alert email
        to our server.
    auth: AuthData object with user_id and email address of the user who
        will file the alert issue.
    subject: the subject of the email message
    body: the body text of the email message
    incident_id: string containing an optional unique incident used to
        de-dupe alert issues.
    msg: the email.Message object that the notification was delivered via.
    trooper_queue: the label specifying the trooper queue that the alert
      notification was sent to. If not given, the notification is sent to
      Infra-Troopers-Alerts.

  Side-effect:
    Creates an issue or issue comment, if no error was reported.
  """
  # Make sure the email address is allowlisted.
  if not IsAllowlisted(from_addr):
    logging.info('Unauthorized %s tried to send alert to %s',
                 from_addr, project_addr)
    return

  formatted_body = 'Filed by %s on behalf of %s\n\n%s' % (
      auth.email, from_addr, body)
  if not IsCommentSizeReasonable(formatted_body):
    logging.info(
        '%s tried to send an alert comment that is too long in %s', from_addr,
        project_addr)
    return

  mc = monorailcontext.MonorailContext(services, auth=auth, cnxn=cnxn)
  mc.LookupLoggedInUserPerms(project)
  with work_env.WorkEnv(mc, services) as we:
    alert_props = GetAlertProperties(
        services, cnxn, project.project_id, incident_id, trooper_queue, msg)
    alert_issue = FindAlertIssue(
        services, cnxn, project.project_id, alert_props['incident_label'])

    if alert_issue:
      # Add a reply to the existing issue for this incident.
      services.issue.CreateIssueComment(
          cnxn, alert_issue, auth.user_id, formatted_body)
    else:
      # Create a new issue for this incident. To preserve previous behavior do
      # not raise filter rule errors.
      alert_issue, _ = we.CreateIssue(
          project.project_id,
          subject,
          alert_props['status'],
          alert_props['owner_id'],
          alert_props['cc_ids'],
          alert_props['labels'],
          alert_props['field_values'],
          alert_props['component_ids'],
          formatted_body,
          raise_filter_errors=False)

    # Update issue using commands.
    lines = body.strip().split('\n')
    uia = commitlogcommands.UpdateIssueAction(alert_issue.local_id)
    commands_found = uia.Parse(
        cnxn, project.project_name, auth.user_id, lines,
        services, strip_quoted_lines=True)

    if commands_found:
      uia.Run(mc, services)


def _GetComponentIDs(proj_config, components):
  comps = ['Infra']
  if components:
    components = components.strip()
  if components:
    comps = [c.strip() for c in components.split(',')]
  return tracker_helpers.LookupComponentIDs(comps, proj_config)


def _GetIncidentLabel(incident_id):
  return 'Incident-Id-%s'.strip().lower() % incident_id if incident_id else ''


def _GetLabels(custom_labels, trooper_queue, incident_label, priority,
               issue_type, oses):
  labels = set(['Restrict-View-Google'.lower()])
  labels.update(
      # Whitespaces in a label can cause UI rendering each of the words as
      # a separate label.
      ''.join(label.split()).lower() for label in itertools.chain(
          custom_labels.split(',') if custom_labels else [],
          [trooper_queue, incident_label, priority, issue_type],
          oses)
      if label
  )
  return list(labels)


def _GetOwnerID(user_svc, cnxn, owner_email):
  if owner_email:
    owner_email = owner_email.strip()
  if not owner_email:
    return framework_constants.NO_USER_SPECIFIED
  emails = [addr for _, addr in email.utils.getaddresses([owner_email])]
  return user_svc.LookupExistingUserIDs(
      cnxn, emails).get(owner_email) or framework_constants.NO_USER_SPECIFIED


def _GetCCIDs(user_svc, cnxn, cc_emails):
  if cc_emails:
    cc_emails = cc_emails.strip()
  if not cc_emails:
    return []
  emails = [addr for _, addr in email.utils.getaddresses([cc_emails])]
  return [userID for _, userID
          in user_svc.LookupExistingUserIDs(cnxn, emails).iteritems()
          if userID is not None]


def _GetPriority(known_labels, priority):
  priority_label = ('Pri-%s' % priority).strip().lower()
  if priority:
    if priority_label in known_labels:
      return priority_label
    logging.info('invalid priority %s for alerts; default to pri-2', priority)

  # XXX: what if 'Pri-2' doesn't exist in known_labels?
  return 'pri-2'


def _GetStatus(proj_config, owner_id, status):
  # XXX: what if assigned and available are not in known_statuses?
  if status:
    status = status.strip().lower()
  if owner_id:
    # If there is an owner, the status must be 'Assigned'.
    if status and status != 'assigned':
      logging.info(
          'invalid status %s for an alert with an owner; default to assigned',
          status)
    return 'assigned'

  if status:
    if tracker_helpers.MeansOpenInProject(status, proj_config):
      return status
    logging.info('invalid status %s for an alert; default to available', status)

  return 'available'


def _GetOSes(known_labels, oses):
  if oses:
    oses = oses.strip().lower()
  if not oses:
    return []

  os_labels_to_lookup = {
      ('os-%s' % os).strip() for os in oses.split(',') if os
  }
  os_labels_to_return = os_labels_to_lookup & known_labels
  invalid_os_labels = os_labels_to_lookup - os_labels_to_return
  if invalid_os_labels:
    logging.info('invalid OSes %s', ','.join(invalid_os_labels))

  return list(os_labels_to_return)


def _GetIssueType(known_labels, issue_type):
  if issue_type:
    issue_type = issue_type.strip().lower()
  if issue_type is None:
    return None

  issue_type_label = 'type-%s' % issue_type
  if issue_type_label in known_labels:
    return issue_type_label

  logging.info('invalid type %s for an alert; default to None', issue_type)
  return None
