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

"""System metrics."""

from __future__ import absolute_import
from __future__ import print_function

import errno
import os
import time

import psutil  # pylint: disable=import-error

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

logger = logging.getLogger(__name__)


_cpu_count_metric = metrics.GaugeMetric(
    'dev/cpu/count',
    description='Number of CPU cores.')
_cpu_time_metric = metrics.FloatMetric(
    'dev/cpu/time',
    description='percentage of time spent by the CPU '
    'in different states.')

_disk_free_metric = metrics.GaugeMetric(
    'dev/disk/free',
    description='Available bytes on disk partition.')
_disk_total_metric = metrics.GaugeMetric(
    'dev/disk/total',
    description='Total bytes on disk partition.')

_inodes_free_metric = metrics.GaugeMetric(
    'dev/inodes/free',
    description='Number of available inodes on '
    'disk partition (unix only).')
_inodes_total_metric = metrics.GaugeMetric(
    'dev/inodes/total',
    description='Number of possible inodes on '
    'disk partition (unix only)')

_mem_free_metric = metrics.GaugeMetric(
    'dev/mem/free',
    description='Amount of memory available to a '
    'process (in Bytes). Buffers are considered '
    'free memory.')

_mem_total_metric = metrics.GaugeMetric(
    'dev/mem/total',
    description='Total physical memory in Bytes.')

_BOOT_TIME = psutil.boot_time()

_disk_read_metric = metrics.CounterMetric(
    'dev/disk/read', start_time=_BOOT_TIME,
    description='Number of Bytes read on disk.')
_disk_write_metric = metrics.CounterMetric(
    'dev/disk/write', start_time=_BOOT_TIME,
    description='Number of Bytes written on disk.')

_uptime_metric = metrics.GaugeMetric(
    'dev/uptime',
    description='Machine uptime, in seconds.')

_load_average_metric = metrics.FloatMetric(
    'dev/proc/load_average',
    description='Number of processes currently '
    'in the system run queue.')

# ts_mon pipeline uses backend clocks when assigning timestamps to metric
# points.  By comparing point timestamp to the point value (i.e. time by
# machine's local clock), we can potentially detect some anomalies (clock
# drift, unusually high metrics pipeline delay, completely wrong clocks, etc).
#
# It is important to gather this metric right before the flush.
_unix_time_metric = metrics.GaugeMetric(
    'dev/unix_time',
    description='Number of milliseconds since epoch'
    ' based on local machine clock.')

_os_name_metric = metrics.StringMetric(
    'proc/os/name',
    description='OS name on the machine')

_os_version_metric = metrics.StringMetric(
    'proc/os/version',
    description='OS version on the machine')

_os_arch_metric = metrics.StringMetric(
    'proc/os/arch',
    description='OS architecture on this machine')

_python_arch_metric = metrics.StringMetric(
    'proc/python/arch',
    description='python userland '
    'architecture on this machine')


def collect_uptime():
  _uptime_metric.set(int(time.time() - _BOOT_TIME))


def collect_cpu_info():
  _cpu_count_metric.set(psutil.cpu_count())

  times = psutil.cpu_times_percent()
  for mode in ('user', 'system', 'idle'):
    _cpu_time_metric.set(getattr(times, mode), {'mode': mode})


def collect_disk_info(mountpoints=None):
  if mountpoints is None:
    mountpoints = [disk.mountpoint for disk in psutil.disk_partitions()]
  for mountpoint in mountpoints:
    _collect_disk_info_single(mountpoint)
    _collect_fs_inode_info(mountpoint)
  _collect_disk_io_info()


def _collect_disk_info_single(mountpoint):
  fields = {'path': mountpoint}

  try:
    usage = psutil.disk_usage(mountpoint)
  except OSError as ex:
    if ex.errno == errno.ENOENT:
      # This happens on Windows when querying a removable drive that
      # doesn't have any media inserted right now.
      pass
    else:
      raise
  else:
    _disk_free_metric.set(usage.free, fields=fields)
    _disk_total_metric.set(usage.total, fields=fields)

  # inode counts are only available on Unix.
  if os.name == 'posix':
    _collect_fs_inode_info(mountpoint)


def _collect_fs_inode_info(mountpoint):
  fields = {'path': mountpoint}
  stats = os.statvfs(mountpoint)
  _inodes_free_metric.set(stats.f_favail, fields=fields)
  _inodes_total_metric.set(stats.f_files, fields=fields)


def _collect_disk_io_info():
  try:
    # pylint: disable=dict-items-not-iterating
    disk_counters = psutil.disk_io_counters(perdisk=True).items()
  except RuntimeError as ex:
    if "couldn't find any physical disk" in str(ex):
      # Disk performance counters aren't enabled on Windows.
      pass
    else:
      raise
  else:
    for disk, counters in disk_counters:
      fields = {'disk': disk}
      _disk_read_metric.set(counters.read_bytes, fields=fields)
      _disk_write_metric.set(counters.write_bytes, fields=fields)


def collect_mem_info():
  # We don't report mem.used because (due to virtual memory) it is not
  # useful.
  mem = psutil.virtual_memory()
  _mem_free_metric.set(mem.available)
  _mem_total_metric.set(mem.total)


def collect_load_avg():
  try:
    avg1, avg5, avg15 = os.getloadavg()
  except OSError:
    pass
  else:
    _load_average_metric.set(avg1, fields={'minutes': 1})
    _load_average_metric.set(avg5, fields={'minutes': 5})
    _load_average_metric.set(avg15, fields={'minutes': 15})


def collect_unix_time():
  _unix_time_metric.set(int(time.time() * 1000))
