# -*- coding: utf-8 -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Chromite email utility functions."""

from __future__ import print_function

import base64
import collections
import gzip
import io
import json
import os
import smtplib
import socket
import sys
import traceback

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import six
from six.moves import http_client as httplib

from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import retry_util

# TODO(fdeng): Cleanup the try-catch once crbug.com/482063 is fixed.
try:
  # pylint: disable=wrong-import-order
  import httplib2
  from googleapiclient.discovery import build as apiclient_build
  from googleapiclient import errors as apiclient_errors
  from oauth2client import file as oauth_client_fileio
  from oauth2client import client
except (RuntimeError, ImportError) as e:
  apiclient_build = None
  oauth_client_fileio = None


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


class MailServer(object):
  """Base class for servers."""

  def Send(self, message):
    """Send the message.

    Override by sub-classes.

    Args:
      message: A MIMEMultipart() object containing the body of the message.

    Returns:
      True if the email was sent, else False.
    """
    raise NotImplementedError('Should be implemented by sub-classes.')


class AuthenticationError(Exception):
  """Error raised when authenticating via oauth2."""


# Represent token in oauth2 token file.
RefreshToken = collections.namedtuple('RefreshToken', (
    'client_id',
    'client_secret',
    'refresh_token',
))


def ReadRefreshTokenJson(path):
  """Returns RefreshToken by reading it from the JSON file.

  Args:
    path: Path to the json file that contains the credential tokens.

  Returns:
    A RefreshToken object.

  Raises:
    AuthenticationError if failed to read from json file.
  """
  try:
    with open(path, 'r') as f:
      data = json.load(f)
      return RefreshToken(
          client_id=str(data['client_id']),
          client_secret=str(data['client_secret']),
          refresh_token=str(data['refresh_token']))
  except (IOError, ValueError) as e:
    raise AuthenticationError(
        'Failed to read refresh token from %s: %s' % (path, e))
  except KeyError as e:
    raise AuthenticationError(
        'Failed to read refresh token from %s: missing key %s' % (path, e))


class GmailServer(MailServer):
  """Gmail server."""

  TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'


  def __init__(self, token_cache_file, token_json_file=None):
    """Initialize GmailServer.

    If token_cache_file contains valid credentials, it will be used.
    If not or the file doesn't exist, will try to load tokens
    from token_json_file. The loaded credentials will be stored to the
    cache file.

    Args:
      token_cache_file: Absolute path to gmail credentials cache file.
      token_json_file: Absolute path to a json file that contains
                       refresh token for gmail.
    """
    self._token_cache_file = token_cache_file
    self._token_json_file = token_json_file

  def _GetCachedCredentials(self):
    """Get credentials from cached file or json file.

    Returns:
      OAuth2Credentials object.

    Raises:
      AuthenticationError on failure to read json file.
    """
    storage = oauth_client_fileio.Storage(self._token_cache_file)
    # Try loading credentials from existing token cache file.
    if os.path.isfile(self._token_cache_file):
      credentials = storage.get()
      if credentials and not credentials.invalid:
        return credentials

    if self._token_json_file is None:
      raise AuthenticationError('Gmail token file path is not provided.')

    # Create new credentials if cache file doesn't exist or not valid.
    refresh_token_json = ReadRefreshTokenJson(self._token_json_file)
    credentials = client.OAuth2Credentials(
        access_token=None,
        client_id=refresh_token_json.client_id,
        client_secret=refresh_token_json.client_secret,
        refresh_token=refresh_token_json.refresh_token,
        token_expiry=None,
        token_uri=self.TOKEN_URI,
        user_agent=None,
        revoke_uri=None)
    credentials.set_store(storage)
    storage.put(credentials)
    return credentials

  def Send(self, message):
    """Send an e-mail via Gmail API.

    Args:
      message: A MIMEMultipart() object containing the body of the message.

    Returns:
      True if the email was sent, else False.
    """
    if not apiclient_build:
      logging.warning('Could not send email: Google API client not installed.')
      return False

    try:
      credentials = self._GetCachedCredentials()
    except AuthenticationError as e:
      logging.warning('Could not get gmail credentials: %s', e)
      return False

    http = credentials.authorize(httplib2.Http())
    service = apiclient_build('gmail', 'v1', http=http)
    try:
      # 'me' represents the default authorized user.
      payload = {
          'raw': base64.urlsafe_b64encode(
              message.as_string().encode('utf-8')).decode('utf-8'),
      }
      service.users().messages().send(userId='me', body=payload).execute()
      return True
    except (apiclient_errors.HttpError, httplib.HTTPException,
            client.Error) as error:
      logging.warning('Could not send email: %s', error)
      return False


class SmtpServer(MailServer):
  """Smtp server."""

  # Note: When importing this module from cbuildbot code that will run on
  # a builder in the golo, set this to constants.GOLO_SMTP_SERVER
  DEFAULT_SERVER = 'localhost'
  # Retry parameters for the actual smtp connection.
  SMTP_RETRY_COUNT = 3
  SMTP_RETRY_DELAY = 30

  def __init__(self, smtp_server=None):
    """Initialize SmtpServer.

    Args:
      smtp_server: The server with which to send the message.
    """
    self._smtp_server = smtp_server or self.DEFAULT_SERVER

  def Send(self, message):
    """Send an email via SMTP

    If we get a socket error (e.g. the SMTP server is not listening or
    timesout), we will retry a few times.  All socket errors will be
    caught here.

    Args:
      message: A MIMEMultipart() object containing the body of the message.

    Returns:
      True if the email was sent, else False.
    """
    def _Send():
      smtp_client = smtplib.SMTP(self._smtp_server)
      recipients = [s.strip() for s in message['To'].split(',')]
      smtp_client.sendmail(message['From'], recipients, message.as_string())
      smtp_client.quit()

    try:
      retry_util.RetryException(socket.error, self.SMTP_RETRY_COUNT, _Send,
                                sleep=self.SMTP_RETRY_DELAY)
      return True
    except socket.error as e:
      logging.warning('Could not send e-mail from %s to %s via %r: %s',
                      message['From'], message['To'], self._smtp_server, e)
      return False


def CreateEmail(subject, recipients, message='', attachment=None,
                extra_fields=None):
  """Create an email message object.

  Args:
    subject: E-mail subject.
    recipients: List of e-mail recipients.
    message: (optional) Message to put in the e-mail body.
    attachment: (optional) text to attach.
    extra_fields: (optional) A dictionary of additional message header fields
                  to be added to the message. Custom field names should begin
                  with the prefix 'X-'.

  Returns:
    A MIMEMultipart object, or None if recipients is empty.
  """
  # Ignore if the list of recipients is empty.
  if not recipients:
    logging.warning('Could not create email: recipient list is emtpy.')
    return None

  extra_fields = extra_fields or {}
  sender = socket.getfqdn()
  msg = MIMEMultipart()
  for key, val in extra_fields.items():
    msg[key] = val
  msg['From'] = sender
  msg['Subject'] = subject
  msg['To'] = ', '.join(recipients)

  msg.attach(MIMEText(message))
  if attachment:
    if isinstance(attachment, six.string_types):
      attachment = attachment.encode()
    s = io.BytesIO()
    with gzip.GzipFile(fileobj=s, mode='wb') as f:
      f.write(attachment)
    part = MIMEApplication(s.getvalue(), _subtype='x-gzip')
    s.close()
    part.add_header('Content-Disposition', 'attachment', filename='logs.txt.gz')
    msg.attach(part)

  return msg


def SendEmail(subject, recipients, server=None, message='',
              attachment=None, extra_fields=None):
  """Send an e-mail job notification with the given message in the body.

  Args:
    subject: E-mail subject.
    recipients: List of e-mail recipients.
    server: A MailServer instance. Default to local SmtpServer.
    message: Message to put in the e-mail body.
    attachment: Text to attach.
    extra_fields: A dictionary of additional message header fields
                  to be added to the message. Custom field names should begin
                  with the prefix 'X-'.
  """
  if server is None:
    server = SmtpServer()
  msg = CreateEmail(subject, recipients, message, attachment, extra_fields)
  if not msg:
    return
  server.Send(msg)


def SendEmailLog(subject, recipients, server=None, message='',
                 inc_trace=True, log=None, extra_fields=None):
  """Send an e-mail with a stack trace and log snippets.

  Args:
    subject: E-mail subject.
    recipients: list of e-mail recipients.
    server: A MailServer instance. Default to local SmtpServer.
    inc_trace: Append a backtrace of the current stack.
    message: Message to put at the top of the e-mail body.
    log: List of lines (log data) to include in the notice.
    extra_fields: (optional) A dictionary of additional message header fields
                  to be added to the message. Custom fields names should begin
                  with the prefix 'X-'.
  """
  if server is None:
    server = SmtpServer()
  if not message:
    message = subject
  message = message[:]

  if inc_trace:
    if sys.exc_info() != (None, None, None):
      trace = traceback.format_exc()
      message += '\n\n' + trace

  attachment = None
  if log:
    message += ('\n\n' +
                '***************************\n' +
                'Last log messages:\n' +
                '***************************\n' +
                ''.join(log[-50:]))
    attachment = ''.join(log)

  SendEmail(subject, recipients, server, message=message,
            attachment=attachment, extra_fields=extra_fields)


def GetUpdatedEmailNotify(builder_run, failure_streak):
  """Return a a list of email_notify values based on the streak.

  Generate a list of email_notify values for notification recipients. Recipients
  are added if the current failure streak is greater than or equal to their
  threshold.

  Args:
    builder_run: BuilderRun for the main cbuildbot run.
    failure_streak: number of consecutive failures for the builder.
  """
  email_notify = []
  for entry in builder_run.config.notification_configs:
    if entry.threshold <= failure_streak:
      email_notify.append(entry.email_notify)

  return email_notify


def GetHealthAlertRecipients(builder_run):
  """Returns a list of email addresses of the health alert recipients."""
  recipients = []
  for entry in builder_run.config.health_alert_recipients:
    if '@' in entry:
      # If the entry is an email address, add it to the list.
      recipients.append(entry)

  return recipients


def SendHealthAlert(builder_run, subject, body, extra_fields=None):
  """Send a health alert.

  Health alerts are only sent for regular buildbots and Pre-CQ buildbots.

  Args:
    builder_run: BuilderRun for the main cbuildbot run.
    subject: The subject of the health alert email.
    body: The body of the health alert email.
    extra_fields: (optional) A dictionary of additional message header fields
                  to be added to the message. Custom field names should begin
                  with the prefix 'X-'.
  """
  if builder_run.InEmailReportingEnvironment():
    server = GmailServer(
        token_cache_file=constants.GMAIL_TOKEN_CACHE_FILE,
        token_json_file=constants.GMAIL_TOKEN_JSON_FILE)
    SendEmail(subject,
              GetHealthAlertRecipients(builder_run),
              server=server,
              message=body,
              extra_fields=extra_fields)
