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

"""Send system monitoring data to the timeseries monitoring API."""

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import random
import time

import psutil

from chromite.lib import commandline
from chromite.lib import cros_logging as logging
from chromite.lib import metrics
from chromite.lib import ts_mon_config
from infra_libs.ts_mon.common import interface

from chromite.scripts.sysmon import git_metrics
from chromite.scripts.sysmon import loop
from chromite.scripts.sysmon import net_metrics
from chromite.scripts.sysmon import osinfo_metrics
from chromite.scripts.sysmon import prod_metrics
from chromite.scripts.sysmon import puppet_metrics
from chromite.scripts.sysmon import system_metrics

logger = logging.getLogger(__name__)


class _MetricCollector(object):
  """Metric collector class."""

  def __init__(self, collect_prod_hosts=False):
    self._collect_osinfo = _TimedCallback(
        callback=osinfo_metrics.collect_os_info,
        interval=60 * 60)
    if collect_prod_hosts:
      logger.info('Enabling prod host metric collection.')
      self._collect_prod_hosts = _TimedCallback(
          callback=prod_metrics.collect_prod_hosts,
          interval=10 * 60)
    else:
      self._collect_prod_hosts = lambda: None

  def __call__(self):
    """Collect metrics."""
    system_metrics.collect_uptime()
    system_metrics.collect_cpu_info()
    system_metrics.collect_disk_info()
    system_metrics.collect_mem_info()
    net_metrics.collect_net_info()
    system_metrics.collect_proc_info()
    system_metrics.collect_load_avg()
    puppet_metrics.collect_puppet_summary()
    git_metrics.collect_git_metrics()
    self._collect_prod_hosts()
    self._collect_osinfo()
    system_metrics.collect_unix_time()  # must be just before flush
    metrics.Flush()

  @property
  def _next_osinfo_collection(self):
    return self._last_osinfo_collection + (60 * 60)


class _TimedCallback(object):
  """Limits callback to one call in a given interval."""

  def __init__(self, callback, interval):
    """Initialize instance.

    Args:
      callback: function to call
      interval: Number of seconds between allowed calls
    """
    self._callback = callback
    self._interval = interval
    self._last_called = time.time() - interval

  def __call__(self):
    if time.time() > self._next_call:
      self._callback()
      self._last_called = time.time()

  @property
  def _next_call(self):
    return self._last_called + self._interval


def main():
  parser = commandline.ArgumentParser(
      description=__doc__,
      default_log_level='DEBUG')
  parser.add_argument(
      '--interval',
      default=60,
      type=int,
      help='time (in seconds) between sampling system metrics')
  parser.add_argument(
      '--collect-prod-hosts',
      action='store_true',
      help='Enable collection of prod host metrics, like roles')
  opts = parser.parse_args()
  opts.Freeze()

  # This returns a 0 value the first time it's called.  Call it now and
  # discard the return value.
  psutil.cpu_times_percent()

  # Wait a random amount of time before starting the loop in case sysmon
  # is started at exactly the same time on all machines.
  time.sleep(random.uniform(0, opts.interval))

  # This call returns a context manager that doesn't do anything, so we
  # ignore the return value.
  ts_mon_config.SetupTsMonGlobalState('sysmon', auto_flush=False)
  # The default prefix is '/chrome/infra/'.
  interface.state.metric_name_prefix = (interface.state.metric_name_prefix
                                        + 'chromeos/sysmon/')

  collector = _MetricCollector(collect_prod_hosts=opts.collect_prod_hosts)
  loop.SleepLoop(callback=collector,
                 interval=opts.interval).loop_forever()


if __name__ == '__main__':
  main()
