# -*- coding: utf-8 -*-
# Copyright 2016 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.

"""Puppet metrics"""

from __future__ import absolute_import
from __future__ import print_function

import time

import yaml  # pylint: disable=import-error

from chromite.lib import cros_logging as logging
from chromite.lib import metrics


logger = logging.getLogger(__name__)

LAST_RUN_FILE = '/var/lib/cros_puppet/state/last_run_summary.yaml'

_config_version_metric = metrics.GaugeMetric(
    'puppet/version/config',
    description='The version of the puppet configuration.'
    '  By default this is the time that the configuration was parsed')
_puppet_version_metric = metrics.StringMetric(
    'puppet/version/puppet',
    description='Version of puppet client installed.')
_events_metric = metrics.GaugeMetric(
    'puppet/events',
    description='Number of changes the puppet client made to the system in its'
    ' last run, by success or failure')
_resources_metric = metrics.GaugeMetric(
    'puppet/resources',
    description='Number of resources known by the puppet client in its last'
    ' run')
_times_metric = metrics.FloatMetric(
    'puppet/times',
    description='Time taken to perform various parts of the last puppet run')
_age_metric = metrics.FloatMetric(
    'puppet/age',
    description='Time since last run')


class _PuppetRunSummary(object):
  """Puppet run summary information."""

  def __init__(self, f):
    """Instantiate instance.

    Args:
      f: file object to read summary from
    """
    self._data = yaml.safe_load(f)

  @property
  def _versions(self):
    """Return mapping of version information."""
    return self._data.get('version', {})

  @property
  def config_version(self):
    """Return config version as int."""
    return self._versions.get('config', -1)

  @property
  def puppet_version(self):
    """Return Puppet version as string."""
    return self._versions.get('puppet', '')

  @property
  def events(self):
    """Return mapping of events information."""
    events = self._data.get('events', {})
    events.pop('total', None)
    return events

  @property
  def resources(self):
    """Return mapping of resources information."""
    resources = self._data.get('resources', {})
    total = resources.pop('total', 0)
    resources['other'] = max(0, total - sum(resources.values()))
    return resources

  @property
  def times(self):
    """Return mapping of time information."""
    times = self._data.get('time', {}).copy()
    times.pop('last_run', None)
    total = times.pop('total', 0)
    times['other'] = max(0, total - sum(times.values()))
    return times

  @property
  def last_run_time(self):
    """Return last run time as UNIX seconds or None."""
    times = self._data.get('time', {})
    return times.get('last_run')


def collect_puppet_summary():
  """Send Puppet run summary metrics."""
  try:
    with open(LAST_RUN_FILE) as f:
      summary = _PuppetRunSummary(f)
  except Exception as e:
    logger.warning(u'Error loading Puppet run summary: %s', e)
  else:
    _config_version_metric.set(summary.config_version)
    _puppet_version_metric.set(str(summary.puppet_version))

    for key, value in summary.events.items():
      _events_metric.set(value, {'result': key})

    for key, value in summary.resources.items():
      _resources_metric.set(value, {'action': key})

    for key, value in summary.times.items():
      _times_metric.set(value, {'step': key})

    if summary.last_run_time is not None:
      _age_metric.set(time.time() - summary.last_run_time)
