# Copyright 2017 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.

"""Helpers for interacting with sheriff-o-matic."""

from __future__ import print_function

from chromite.lib import auth
from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import retry_util
from chromite.cbuildbot import topology


# Methods
POST_METHOD = 'POST'


# The following classes are intended to marshal into json matching
# the structures in
# https://cs.chromium.org/chromium/infra/go/src/infra/monitoring/messages/alerts.go  # pylint: disable=line-too-long

class Alert(object):
  """JSON structure for a single Sheriff-o-matic Alert."""
  def __init__(self, key, title, body, severity, time, start_time, links, tags,
               atype, extension):
    self.key = key
    self.title = title
    self.body = body
    self.severity = severity
    self.time = time
    self.start_time = start_time
    self.links = links
    self.tags = tags
    self.type = atype
    self.extension = extension


class AlertsSummary(object):
  """JSON structure for full set of Sheriff-o-matic alerts."""
  def __init__(self, alerts, revision_summaries, timestamp):
    self.alerts = alerts
    self.revision_summaries = revision_summaries
    self.timestamp = timestamp


class Link(object):
  """JSON structure for a link within an alert."""
  def __init__(self, title, href):
    self.title = title
    self.href = href


class AlertedBuilder(object):
  """JSON structure for a a single failing builder within an alert."""
  def __init__(self, name, url, start_time, first_failure, latest_failure):
    self.name = name
    self.url = url
    self.start_time = start_time
    self.first_failure = first_failure
    self.latest_failure = latest_failure


# The following classes do not directly map into go structures but are
# parsed by code within
# https://cs.chromium.org/chromium/infra/go/src/infra/appengine/sheriff-o-matic/elements/  # pylint: disable=line-too-long

class CrosStageFailure(object):
  """JSON structure with details on a stage that failed."""
  def __init__(self, name, status, logs, links, notes):
    self.name = name
    self.status = status
    self.logs = logs
    self.links = links
    self.notes = notes


class CrosBuildFailure(object):
  """JSON structure with details on a build that failed."""
  def __init__(self, stages, builders):
    self.stages = stages
    self.builders = builders


class SheriffOMaticResponseException(Exception):
  """Exception got from Sheriff-o-Matic Response."""


class SheriffOMaticClient(object):
  """Sheriff-o-Matic client to interact with the Sheriff-o-Matic frontend."""

  def __init__(self, service_account=None, insecure=False, host=None):
    """Init a SheriffOMaticClient instance.

    Args:
      service_account: The path to the service account json file.
      insecure: Fall-back to insecure HTTP connection.
      host: The Sheriff-o-Matic instance to interact with.
    """
    self.http = auth.AuthorizedHttp(
        auth.GetAccessToken,
        service_account_json=service_account)
    self.insecure = insecure
    self.host = (self._GetHost() if host is None else host).strip()

  def _GetHost(self):
    """Get Sheriff-o-matic Server host from topology."""
    return topology.topology.get(topology.SHERIFFOMATIC_HOST_KEY)

  def SendRequest(self, url, method, body, dryrun):
    """Generic Sheriff-o-Matic request.

    Args:
      url: Sheriff-o-Matic url to send requests.
      method: HTTP method to perform, such as GET, POST, DELETE.
      body: The entity body to be sent with the request (a string object).
            See httplib2.Http.request for details.
      dryrun: Whether a dryrun.

    Returns:
      A dict of response entity body if the request succeeds; else, None.
      See httplib2.Http.request for details.

    Raises:
      SheriffOMaticResponseException when response['status'] is invalid.
    """
    if dryrun:
      logging.info('Dryrun mode is on; Would have made a request '
                   'with url %s method %s body:\n%s', url, method, body)
      return

    def try_method():
      response, content = self.http.request(
          url,
          method,
          body=body,
          headers={'Content-Type': 'application/json'},
      )

      if int(response['status']) // 100 != 2:
        raise SheriffOMaticResponseException(
            'Got a %s response from Sheriff-o-Matic with url: %s\n'
            'content: %s' % (response['status'], url, content))

      return content

    return retry_util.GenericRetry(lambda e: isinstance(e, Exception), 3,
                                   try_method)

  def SendAlerts(self, summary_json, dryrun=False):
    """Upload alerts summary to Sheriff-o-matic.

    Args:
      summary_json: JSON version of AlertsSummary structure.
      dryrun: Whether a dryrun.

    Returns:
      Results of HTTP request.
    """
    url = '%(scheme)s://%(hostname)s/api/v1/alerts/%(tree)s' % {
        'scheme': 'http' if self.insecure else 'https',
        'hostname': self.host,
        'tree': constants.SOM_TREE,
    }
    return self.SendRequest(url, POST_METHOD, summary_json, dryrun=dryrun)
