"""Module for recording metrics and uploading to Google Cloud Logging.

There are 3 methods of logging:
1) Stackdriver / Cloud Logging API
2) Local Logging
3) Fluentd Agent

Setup:
  1) Stackdriver / Cloud Logging API, during application setup you should call:

    project_name = 'google.com:cast-cq-staging'
    logger_name = 'cast_cq.master'
    cloud_logging.ConfigureLogger(project_name, logger_name)

  2) Local Logging, this is used by default if you do not configure the cloud
  logger or enable the fluentd logger

  3) For Fluentd Agent, during application setup you should call:

    namespace = "buildbot"
    host = "127.0.0.0"
    port = 24224
    cloud_logging.EnableFluentdLogger(namespace, host, port)

  There are few caveats when using the fluentd agent:
  - The Google Cloud project will be inferred by the agent (either by explicitly
    setting the project in the configuration or implicitly by the IAM Role)
    that's how it determines which project to upload the logs to.
  - Since we're using a version of the Google Cloud agent, it assumes that the
    host it's running on is a GCE instance (which it may not). The consequence
    of this is that the logs will be grouped into a GCE resource log like
    "GCE VM Instance, <id>" and NOT "Global"
  - Severity is ignored when using the agent
  - Additional labels are also not passed to the agent

Usage:
  Then, throughout your application, you can use:

  import cloud_logging

  t = cloud_logging.Timer('test_timer').Start()
  # do something interesting...
  t.Stop()

  with cloud_logging.Timer('test_timer') as t:
    # do something interesting...
    t.AddAttribute('a', 'b')

  ev = cloud_logging.LogEvent('test_msg', value='Something to log').Log()
  cloud_logging.Info('info_message', value='Something to log').Log()
  cloud_logging.Error('error_message', value='Something to log').Log()
"""
import atexit
import logging
import os
import socket
import threading
import time
import traceback

from fluent import event as fluentd_event
from fluent import sender as fluentd  # TODO(b/70284159): switch to asyncsender

from google.cloud import logging as gcl  # pylint: disable=ungrouped-imports
from google.gax import errors
from google.gax import grpc
from google.protobuf import json_format
import six

# Subset of supported severity levels:
# https://cloud.google.com/logging/docs/api/reference/rest/v2/LogEntry#LogSeverity
DEBUG = 'DEBUG'
INFO = 'INFO'
WARNING = 'WARNING'
ERROR = 'ERROR'

SEVERITY_LEVELS = [DEBUG, INFO, WARNING, ERROR]
# Global instances of configured cloud client/loggers
_GLOBAL_CLIENT = None
_GLOBAL_LOGGER = None
_GLOBAL_THREAD = None
_GLOBAL_LABELS = {}


class BaseError(Exception):
  """Base error."""


class ConfigurationError(BaseError):
  """Base error for invalid log configurations."""


class EventError(BaseError):
  """Base error for Metrics."""


class TimerError(BaseError):
  """Base error for Timers."""


class StrictAttributesError(BaseError):
  """Base Error for StrictAttributes decorator."""


class LoggerError(BaseError):
  """Base error for errors raised in logger."""

  def __init__(self, original_error):
    super(LoggerError, self).__init__(self)
    self.original_error = original_error
    self.original_trace = traceback.format_exc()

  def __str__(self):
    return self.original_trace


class LoggerGaxError(LoggerError):
  """Class for gax errors raised in logger."""


class LogEvent(object):
  """A high level LogEvent class used for logging events and data."""

  def __init__(self, name, attributes=None, value=None, severity=None):
    """Initialize a LogEvent.

    Args:
      name: The name of the event being timed.
      attributes: A dict representing attributes to be recorded with this timer.
      value: A value to include in the Metric.
      severity: A string representing the log severity. One of:
          'DEBUG', 'INFO', 'WARNING', 'ERROR' or None.
    """
    self._name = self._Sanitize(name)
    self._attributes = {}
    if not attributes:
      attributes = {}
    self.AddAttributes(attributes)
    self._host = socket.getfqdn()
    self._recorded_at = self._Now()
    self._logged = False
    self._value = self._Sanitize(value)
    self._type = 'general'
    self._severity = severity

  @property
  def type(self):
    """Returns the type of event."""
    return self._type

  @property
  def value(self):
    """Returns the value for this event."""
    return self._value

  @value.setter
  def value(self, value):
    """Sets the value for this event."""
    self._value = self._Sanitize(value)

  @property
  def severity(self):
    """Returns the severity of event."""
    return self._severity

  @severity.setter
  def severity(self, severity):
    """Sets the severity of this event.

    Only valid severity values will be accepted, all others will fail silently.

    Args:
      severity: A string representing the log severity. One of:
          'DEBUG', 'INFO', 'WARNING', 'ERROR' or None.
    """
    self._severity = None
    if severity in SEVERITY_LEVELS:
      self._severity = severity

  @property
  def recorded_at(self):
    """Get the timestamp for when this event was recorded."""
    return self._recorded_at

  @property
  def name(self):
    return self._name

  @property
  def host(self):
    return self._host

  @property
  def attributes(self):
    return self._attributes

  def _Sanitize(self, value):
    """Sanitizes arguments so they can be uploaded to GCL.

    If it is a supported primitive that will be returned, otherwise its str
    representation will be used.

    This will also iterate through lists & dicts and sanitize their values.

    Args:
      value: The value to sanitize.

    Returns:
      The sanitized version of value.
    """
    if isinstance(value, (six.integer_types, float, bool)):
      return value
    if isinstance(value, list):
      return [self._Sanitize(v) for v in value]
    if isinstance(value, dict):
      return {self._Sanitize(key): self._Sanitize(v)
              for key, v in six.iteritems(value)}
    try:
      return str(value)
    except Exception as e:  # pylint: disable=broad-except
      return 'Could not sanitize object of type %s: %s' % (type(value), e)

  def AddAttributes(self, attributes):
    """Add more attributes to the event.

    Args:
      attributes: A dict of attributes to add to the current attribute list.
                  They will override other attributes with the same keys.

    Returns:
      self.
    """
    if not attributes:
      return self
    for key, value in six.iteritems(attributes):
      self.AddAttribute(key, value)
    return self

  def AddAttribute(self, name, value):
    """Add a single attribute to the event.

    Args:
      name: The key to be used in the attribute dict.
      value: The value to put for the given key. Note, if the key already
             existed its value will be overridden.

    Returns:
      self.
    """
    self._attributes[self._Sanitize(name)] = self._Sanitize(value)
    return self

  def AsDict(self):
    """Returns a dictionary representation of this event."""
    result = {
        'name': self.name,
        'recorded_at_utc_usec': self.recorded_at,
        'value': self.value,
        'type': self.type,
        'host': self.host,
        'attributes': self.attributes
    }
    return result

  def Valid(self):
    """Returns if this event is valid."""
    return True

  def Log(self):
    """Log this event.

    Raises:
      EventError: If the event is invalid.
    """
    if not self.Valid():
      raise EventError('Event not valid.')
    if not self._logged:
      _SendEvent(self, severity=self._severity)
      self._logged = True

  def _Now(self):
    """Returns the UTC usec timestamp for now."""
    return time.time() * 1000 * 1000


class Timer(LogEvent):
  """A simpler timer object to record & log the duration of something."""

  def __init__(self, name, attributes=None, severity=None):
    """Initialize a timer.

    Remember to call Start() to begin timing.

    Args:
      name: The name of the event being timed.
      attributes: A dict representing attributes to be recorded with this timer.
      severity: A string representing the log severity. One of:
          'DEBUG', 'INFO', 'WARNING', 'ERROR' or None.
    """
    super(Timer, self).__init__(name, attributes=attributes, severity=severity)
    self._started_at = None
    self._finished_at = None
    self._type = 'timer'

  def Start(self):
    """Starts the timer.

    Returns:
      self.
    """
    self._started_at = self._Now()
    return self

  def Stop(self):
    """Stops the timer and records the result.

    Note that the timer must have been started.

    Returns:
      self.

    Raises:
      TimerError: If the timer has not yet been started.
    """
    if not self.started:
      raise TimerError('Timer not yet started.')
    self._finished_at = self._Now()
    self.Log()
    return self

  @property
  def started(self):
    """Returns boolean if this timer has been started."""
    return self._started_at is not None

  @property
  def finished(self):
    """Returns boolean if this timer has been completed."""
    return self._finished_at is not None

  def Time(self):
    """Returns the value recorded by this timer.

    Returns:
      The timed value.

    Raises:
      TimerError: If the timer has not been started or completed.
    """
    if not self.started:
      raise TimerError('Timer not yet started.')
    if not self.finished:
      raise TimerError('Timer not yet finished.')
    return self._finished_at - self._started_at

  @property
  def value(self):
    return self.Time()

  @property
  def recorded_at(self):
    return self._finished_at

  def Valid(self):
    try:
      self.Time()
      return True
    except TimerError:
      return False

  def __enter__(self):
    self.Start()
    return self

  def __exit__(self, *args):
    self.Stop()


class StrictAttributes(object):
  """Decorator for LogEvents that require a fixed set of attributes.

  This decorator should be used when collecting metrics to be uploaded to
  BigQuery. All attributes to be collected must be included in valid_attributes,
  mapped to their default values. Any valid_attributes not added before Log()
  will be included with the specified default value.

  Sample Usage:

  VALID_ATTRIBUTES = {
      'status': StrictAttributes.DEFAULT_STRING,
      'count': StrictAttributes.DEFAULT_INT }

  @StrictAttributes(VALID_ATTRIBUTES)
  class MyLogger(Timer):
    ...
  """
  # TODO(adrexler): Migrate valid_attributes to protobuf.

  # Default values for all accepted attribute datatypes.
  DEFAULT_STRING = ''
  DEFAULT_BOOL = False
  DEFAULT_LIST = []
  DEFAULT_DICT = {}
  DEFAULT_INT = -1
  DEFAULT_FLOAT = float(DEFAULT_INT)
  try:
    DEFAULT_LONG = long(DEFAULT_INT)
  except NameError:
    DEFAULT_LONG = int(DEFAULT_INT)  # pylint: disable=redefined-variable-type

  def __init__(self, valid_attributes):
    """Constructor.

    Args:
      valid_attributes: All acceptable attributes, mapped to default values.
    """
    self._valid_attributes = valid_attributes

  def __call__(self, cls, *args, **kwargs):
    """Returns MetricsCollector class, extending cls."""
    if not issubclass(cls, LogEvent):
      raise StrictAttributesError('%s does not extend LogEvent!', cls)
    valid_attributes = self._valid_attributes

    class MetricsCollector(cls):
      """Extension of LogEvent child cls, with strict attributes."""

      def __init__(self, *args, **kwargs):
        self._valid_attributes = valid_attributes
        super(MetricsCollector, self).__init__(*args, **kwargs)

      def AddAttribute(self, name, value):
        """Adds value for attribute after checking that attribute is valid."""
        if name not in self._valid_attributes:
          logging.error('%s is not a valid attribute!', name)
          return
        super(MetricsCollector, self).AddAttribute(name, value)

      def Log(self):
        """Adds specified default values for missing attributes and logs."""
        for attribute in self._valid_attributes:
          if attribute not in self._attributes:
            self.AddAttribute(attribute, self._valid_attributes[attribute])
        super(MetricsCollector, self).Log()
    return MetricsCollector


class BatchThread(threading.Thread):
  """A simple thread worker to call commit on the Batch Logger."""

  def __init__(self, duration, err_limit=3, sleep=2.0):
    super(BatchThread, self).__init__()
    self._duration = duration
    self._sleep = sleep
    self._stop = threading.Event()
    self._err_limit = err_limit

  def run(self):
    while not self._stop.isSet():
      time.sleep(self._duration)
      if not _CommitWithRetry(self._sleep, self._err_limit):
        logging.error('Terminated cloud logging due to non-transient error')
        self._stop.set()

  def join(self, timeout=None):
    self._stop.set()
    super(BatchThread, self).join(timeout)


def Debug(*args, **kwargs):
  return LogEvent(*args, severity=DEBUG, **kwargs)


def Info(*args, **kwargs):
  return LogEvent(*args, severity=INFO, **kwargs)


def Warn(*args, **kwargs):
  return LogEvent(*args, severity=WARNING, **kwargs)


def Error(*args, **kwargs):
  return LogEvent(*args, severity=ERROR, **kwargs)


def _SendEvent(event, severity=None):
  """Log a metric.

  Args:
    event: A LogEvent to log. Must have an AsDict method implemented.
    severity: A string representing the log severity. This will be ignored if
              fluentd is enabled.

  Raises:
    LoggerGaxError: If GaxError other then DEADLINE_EXCEEDED was
                    raised during logger call.
    LoggerError: If any error other then ParseError or GaxError was
                 raised during logger call.
  """
  if fluentd.get_global_sender():
    fluentd_event.Event(None, event.AsDict())
  elif _GLOBAL_LOGGER:
    try:
      _GLOBAL_LOGGER.log_struct(
          event.AsDict(), labels=_GLOBAL_LABELS, severity=severity)
    except errors.GaxError as e:
      if grpc.exc_to_code(e.cause) != grpc.StatusCode.DEADLINE_EXCEEDED:
        raise LoggerGaxError(e)
      logging.exception('Gax RPC Deadline exceeded while push to log event %s'
                        ' with labels %s, not expecting event loss in cloud',
                        event.AsDict(), _GLOBAL_LABELS)
    except json_format.ParseError as e:
      logging.exception('Unable to log event %s with labels %s'
                        ' event will not be reported to cloud',
                        event.AsDict(), _GLOBAL_LABELS)
    except Exception as e:  # pylint: disable=broad-except
      raise LoggerError(e)
  else:
    logging.info(event.AsDict())


def _CommitWithRetry(sleep=2.0, retries=3):
  """Commiting event queue. Dispatching errors and recover if possible.

  The only transient error we are aware of is a Gax RetryError.
  In 99% cases we succeed from 3rd commit and will not succeed after that
  without clearing commit queue.
  For other then Gax Retry Error we will not recover, so returning False

  Args:
    sleep: Sleep period between retries in case of error.
    retries: Maximum number of commits before clearing queue.
  Return:
    Boolean if the batch process should continue
  """
  while retries > 0:
    try:
      _GLOBAL_LOGGER.commit()
      return True
    except errors.RetryError as e:
      retries -= 1
      queue_size = len(_GLOBAL_LOGGER.entries[:])
      err = str(e)
      logging.exception('Gax Retry Error while commit log buffer,'
                        ' %d retries left,%s %d events in queue', retries,
                        '' if retries else ' dropping', queue_size)
      if retries > 0:
        Warn('RetryError', value=queue_size, attributes={
             'retries_left': retries, 'error': err,
             'dropping_queue': False}).Log()
        time.sleep(sleep)
      else:
        del _GLOBAL_LOGGER.entries[:]
        Warn('RetryError', value=queue_size, attributes={
             'retries_left': 0, 'error': err,
             'dropping_queue': True}).Log()
    except errors.GaxError as e:
      logging.exception('Gax Error while commit log buffer, stopping batch')
      return False
    except Exception as e:  # pylint: disable=broad-except
      logging.exception('Unexpected Error while commit log buffer,'
                        ' stopping batch')
      return False
  return True

def ConfigureLogger(project_name, logger_name, labels=None, batch_time=None,
                    batch_err_limit=3):
  """Configure a Cloud Logger.

  Does NOT enable logging to a fluentd agent. See EnableFluentdLogger()

  Args:
    project_name: The name of the project to log to.
    logger_name: The name of the logger.
    labels: An optional dict of labels to apply to each message.
    batch_time: use a batch logger to send logs every n seconds.
    batch_err_limit: max consecutive errors before batch logging is terminated.

  Raises:
    ConfigurationError: If no credentials were found.
  """
  if 'GOOGLE_APPLICATION_CREDENTIALS' not in os.environ:
    raise ConfigurationError(
        ('No credentials found. Make sure a json based key is available in the '
         'GOOGLE_APPLICATION_CREDENTIALS env var.')
    )

  global _GLOBAL_CLIENT
  global _GLOBAL_LOGGER
  global _GLOBAL_THREAD
  _GLOBAL_CLIENT = gcl.Client(project=project_name)
  _GLOBAL_LOGGER = _GLOBAL_CLIENT.logger(logger_name)
  if batch_time:
    _GLOBAL_LOGGER = _GLOBAL_LOGGER.batch()
    _GLOBAL_THREAD = BatchThread(batch_time, batch_err_limit)
    _GLOBAL_THREAD.start()
  _GLOBAL_LABELS['host'] = socket.getfqdn()
  if labels:
    _GLOBAL_LABELS.update(labels)

def SafeConfigureLogger(*args, **kwargs):
  """Configures a Cloud Logger, if possible. Otherwise fails silently.

     Does NOT enable logging to a fluentd agent. See EnableFluentdLogger()
  """
  try:
    ConfigureLogger(*args, **kwargs)
  except ConfigurationError:
    logging.error('Unable to configure cloud logging: No GAE credentials '
                  'found. Logging to console only.')

def EnableFluentdLogger(namespace, host="127.0.0.1", port=24224):
  """Enable logging to a fluentd agent for logging to Google Cloud.

  This disables any other form of logging, including both the Cloud Logging API
  and local logging.

  Args:
    namespace: The namespace for logs in this application. For example
               "buildbot", which becomes referenced in Google Cloud as
               logName: "projects/<project>/logs/<namespace>"
    host: The hostname or IP the fluentd agent lives on.
    port: The port the fluentd agent is listening on.
  """
  if fluentd.get_global_sender() is None:
    fluentd.setup(namespace, host=host, port=port)

@atexit.register
def StopLogger():
  """
    Stop the batch logger thread and/or fluentd logger if started. No more
    logs will be sent.

    This will be executed on application termination
  """
  if _GLOBAL_THREAD:
    _GLOBAL_THREAD.join()

  if fluentd.get_global_sender():
    fluentd.close()
