# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import mock
import sys
import time
import unittest

from infra_libs.ts_mon.common import distribution
from infra_libs.ts_mon.common import errors
from infra_libs.ts_mon.common import interface
from infra_libs.ts_mon.common import metric_store
from infra_libs.ts_mon.common import metrics
from infra_libs.ts_mon.common import targets
from infra_libs.ts_mon.protos import metrics_pb2


class TestBase(unittest.TestCase):
  def setUp(self):
    super(TestBase, self).setUp()
    target = targets.TaskTarget('test_service', 'test_job',
                                'test_region', 'test_host')
    self.mock_state = interface.State(target=target)
    self.state_patcher = mock.patch('infra_libs.ts_mon.common.interface.state',
                                    new=self.mock_state)
    self.state_patcher.start()

    self.mock_state.target = targets.TaskTarget(
        service_name='service', job_name='job', region='region',
        hostname='hostname', task_num=0)

    self.time_fn = mock.create_autospec(time.time, spec_set=True)
    self.mock_state.store = metric_store.InProcessMetricStore(
        self.mock_state, self.time_fn)

  def tearDown(self):
    self.state_patcher.stop()
    super(TestBase, self).tearDown()

  def _test_proto(self, metric, set_fn, value_type, stream_kind):
    self.time_fn.return_value = 100.3
    interface.register(metric)
    set_fn(metric)

    self.time_fn.return_value = 1000.6
    proto = list(interface._generate_proto())[0]
    data_set = proto.metrics_collection[0].metrics_data_set[0]
    data = data_set.data[0]

    self.assertEqual(stream_kind, data_set.stream_kind)
    self.assertEqual(value_type, data_set.value_type)
    self.assertEqual(100, data.start_timestamp.seconds)
    self.assertEqual(1000, data.end_timestamp.seconds)
    self.assertFalse(data_set.annotations.HasField('unit'))

    return data


class MetricTest(TestBase):

  def test_properties(self):
    field_spec = [metrics.StringField('string')]
    m1 = metrics.Metric('/foo', 'foo', field_spec, 'us')
    self.assertEquals(m1.name, 'foo')
    self.assertEquals(m1.field_spec, field_spec)
    self.assertEquals(m1.units, 'us')

  def test_equality(self):
    field_spec = [metrics.StringField('string')]
    m = metrics.Metric('/foo', 'foo', field_spec, 'us')
    self.assertEquals(m, m)

  def test_init_too_many_fields(self):
    fields = [metrics.StringField('field%d' % i) for i in range(8)]
    with self.assertRaises(errors.MonitoringTooManyFieldsError) as e:
      metrics.Metric('test', 'test', fields)
    self.assertEquals(e.exception.metric, 'test')
    self.assertEquals(len(e.exception.fields), 8)

  def test_set_wrong_number_of_fields(self):
    m = metrics.StringMetric('foo', 'foo', [metrics.IntegerField('asdf')])
    with self.assertRaises(errors.WrongFieldsError):
      m.set('bar', {'asdf': 1, 'foo': 2})

  def test_set_list_fields(self):
    m = metrics.StringMetric('foo', 'foo', [metrics.IntegerField('asdf')])
    with self.assertRaises(ValueError):
      m.set('bar', [1])

  def test_set_object_fields(self):
    m = metrics.StringMetric('foo', 'foo', [metrics.IntegerField('asdf')])
    with self.assertRaises(ValueError):
      m.set('bar', object())

  def test_register_unregister(self):
    self.assertEquals(0, len(self.mock_state.metrics))
    m = metrics.Metric('test', 'test', None)
    self.assertEquals(1, len(self.mock_state.metrics))
    m.unregister()
    self.assertEquals(0, len(self.mock_state.metrics))

  def test_reset(self):
    m = metrics.StringMetric('test', 'test', None)
    self.assertIsNone(m.get())
    m.set('foo')
    self.assertEqual('foo', m.get())
    m.reset()
    self.assertIsNone(m.get())

  def test_populate_data_set(self):
    interface.state.metric_name_prefix = '/infra/test/'
    scenarios = [
        (metrics.CounterMetric, 'desc', metrics_pb2.CUMULATIVE),
        (metrics.GaugeMetric, 'desc', metrics_pb2.GAUGE)]
    for m_ctor, desc, stream_kind in scenarios:
      m = m_ctor(m_ctor.__name__, desc, None,
                 units=metrics.MetricsDataUnits.SECONDS)
      data_set = metrics_pb2.MetricsDataSet()
      m.populate_data_set(data_set)

      self.assertEqual(stream_kind, data_set.stream_kind)
      self.assertEqual('/infra/test/%s' % m_ctor.__name__, data_set.metric_name)
      self.assertEqual(desc, data_set.description)
      self.assertEqual('s', data_set.annotations.unit)

  def test_populate_data(self):
    m = metrics.CounterMetric('test', 'test', None)
    data = metrics_pb2.MetricsData()
    m.populate_data(data, 100.4, 1000.6, {}, 5)

    self.assertEqual(100, data.start_timestamp.seconds)
    self.assertEqual(1000, data.end_timestamp.seconds)

  def test_populate_field_descriptor(self):
    data_set_pb = metrics_pb2.MetricsDataSet()
    m = metrics.Metric('test', 'test', [
        metrics.IntegerField('a'),
        metrics.BooleanField('b'),
        metrics.StringField('c'),
    ])
    m._populate_field_descriptors(data_set_pb)

    field_type = metrics_pb2.MetricsDataSet.MetricFieldDescriptor
    self.assertEqual(3, len(data_set_pb.field_descriptor))

    self.assertEqual('a', data_set_pb.field_descriptor[0].name)
    self.assertEqual(field_type.INT64,
                     data_set_pb.field_descriptor[0].field_type)

    self.assertEqual('b', data_set_pb.field_descriptor[1].name)
    self.assertEqual(field_type.BOOL,
                     data_set_pb.field_descriptor[1].field_type)

    self.assertEqual('c', data_set_pb.field_descriptor[2].name)
    self.assertEqual(field_type.STRING,
                     data_set_pb.field_descriptor[2].field_type)

  def test_populate_fields(self):
    data = metrics_pb2.MetricsData()
    m = metrics.Metric('test', 'test', [
        metrics.IntegerField('a'),
        metrics.BooleanField('b'),
        metrics.StringField('c'),
    ])
    m._populate_fields(data, (1, True, 'test'))

    self.assertEqual(3, len(data.field))

    self.assertEqual('a', data.field[0].name)
    self.assertEqual(1, data.field[0].int64_value)

    self.assertEqual('b', data.field[1].name)
    self.assertTrue(data.field[1].bool_value)

    self.assertEqual('c', data.field[2].name)
    self.assertEqual('test', data.field[2].string_value)

  def test_bad_description(self):
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', 123, None)
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', '', None)
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', None, None)

  def test_bad_field_spec(self):
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', 'desc', ['abc'])
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', 'desc', ('abc',))
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', 'desc', [123])
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.Metric('test', 'desc', [None])


class FieldValidationTest(TestBase):
  def test_string_field(self):
    f = metrics.StringField('name')
    f.validate_value('', 'string')
    f.validate_value('', u'string')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 123)
    if sys.version_info.major < 3:
      with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
        f.validate_value('', long(123))
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', True)
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', None)
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 12.34)

  def test_integer_field(self):
    f = metrics.IntegerField('name')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 'string')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', u'string')
    f.validate_value('', 123)
    if sys.version_info.major < 3:
      f.validate_value('', long(123))
    f.validate_value('', True)  # Python allows this *shrug*
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', None)
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 12.34)

  def test_boolean_field(self):
    f = metrics.BooleanField('name')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 'string')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', u'string')
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 123)
    if sys.version_info.major < 3:
      with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
        f.validate_value('', long(123))
    f.validate_value('', True)
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', None)
    with self.assertRaises(errors.MonitoringInvalidFieldTypeError):
      f.validate_value('', 12.34)

  def test_invalid_field_name(self):
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.StringField('foo', 'desc', [metrics.StringField(' ')])
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.StringField('foo', 'desc', [metrics.StringField('123')])
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.StringField('foo', 'desc', [metrics.StringField('')])
    with self.assertRaises(errors.MetricDefinitionError):
      metrics.StringField('foo', 'desc', [metrics.StringField(u'\U0001F4A9')])

  def test_equality(self):
    f = metrics.IntegerField('name')
    self.assertEquals(f, f)


class StringMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.StringMetric('t', 't', None), lambda m: m.set('aaa'),
        metrics_pb2.STRING, metrics_pb2.GAUGE)
    self.assertEqual('aaa', proto.string_value)

  def test_set(self):
    m = metrics.StringMetric('test', 'test', None)
    m.set('hello world')
    self.assertEquals(m.get(), 'hello world')

  def test_non_string_raises(self):
    m = metrics.StringMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())

  def test_is_cumulative(self):
    m = metrics.StringMetric('test', 'test', None)
    self.assertFalse(m.is_cumulative())


class BooleanMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.BooleanMetric('test', 'test', None),
        lambda m: m.set(True),
        metrics_pb2.BOOL, metrics_pb2.GAUGE)
    self.assertTrue(proto.bool_value)

  def test_set(self):
    m = metrics.BooleanMetric('test', 'test', None)
    m.set(False)
    self.assertEquals(m.get(), False)

  def test_non_bool_raises(self):
    m = metrics.BooleanMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set('True')
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(123)

  def test_is_cumulative(self):
    m = metrics.BooleanMetric('test', 'test', None)
    self.assertFalse(m.is_cumulative())


class CounterMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.CounterMetric('c', 'test', None),
        lambda m: m.increment_by(5),
        metrics_pb2.INT64, metrics_pb2.CUMULATIVE)
    self.assertEqual(5, proto.int64_value)

  def test_set(self):
    m = metrics.CounterMetric('test', 'test', None)
    m.set(10)
    self.assertEquals(m.get(), 10)

  def test_increment(self):
    m = metrics.CounterMetric('test', 'test', None)
    m.set(1)
    self.assertEquals(m.get(), 1)
    m.increment()
    self.assertEquals(m.get(), 2)
    m.increment_by(3)
    self.assertAlmostEquals(m.get(), 5)

  def test_decrement_raises(self):
    m = metrics.CounterMetric('test', 'test', None)
    m.set(1)
    with self.assertRaises(errors.MonitoringDecreasingValueError):
      m.set(0)
    with self.assertRaises(errors.MonitoringDecreasingValueError):
      m.increment_by(-1)

  def test_non_int_raises(self):
    m = metrics.CounterMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(1.5)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.increment_by(1.5)

  def test_multiple_field_values(self):
    m = metrics.CounterMetric('test', 'test', [metrics.StringField('foo')])
    m.increment({'foo': 'bar'})
    m.increment({'foo': 'baz'})
    m.increment({'foo': 'bar'})
    with self.assertRaises(errors.WrongFieldsError):
      m.get()
    self.assertIsNone(m.get({'foo': ''}))
    self.assertEquals(2, m.get({'foo': 'bar'}))
    self.assertEquals(1, m.get({'foo': 'baz'}))

  def test_is_cumulative(self):
    m = metrics.CounterMetric('test', 'test', None)
    self.assertTrue(m.is_cumulative())

  def test_get_all(self):
    m = metrics.CounterMetric('test', 'test', [metrics.StringField('foo')])
    m.increment({'foo': ''})
    m.increment({'foo': 'bar'})
    self.assertEqual([
        (('',), 1),
        (('bar',), 1),
    ], sorted(m.get_all()))


class GaugeMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.GaugeMetric('test', 'test', None), lambda m: m.set(5),
        metrics_pb2.INT64, metrics_pb2.GAUGE)
    self.assertEqual(5, proto.int64_value)

  def test_set(self):
    m = metrics.GaugeMetric('test', 'test', None)
    m.set(10)
    self.assertEquals(m.get(), 10)
    m.set(sys.maxint + 1)
    self.assertEquals(m.get(), sys.maxint + 1)

  def test_non_int_raises(self):
    m = metrics.GaugeMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())

  def test_is_cumulative(self):
    m = metrics.GaugeMetric('test', 'test', None)
    self.assertFalse(m.is_cumulative())


class CumulativeMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.CumulativeMetric('c', 'test', None),
        lambda m: m.increment_by(5.2),
        metrics_pb2.DOUBLE, metrics_pb2.CUMULATIVE)
    self.assertAlmostEqual(5.2, proto.double_value)

  def test_set(self):
    m = metrics.CumulativeMetric('test', 'test', None)
    m.set(3.14)
    self.assertAlmostEquals(m.get(), 3.14)

  def test_decrement_raises(self):
    m = metrics.CumulativeMetric('test', 'test', None)
    m.set(3.14)
    with self.assertRaises(errors.MonitoringDecreasingValueError):
      m.set(0)
    with self.assertRaises(errors.MonitoringDecreasingValueError):
      m.increment_by(-1)

  def test_non_number_raises(self):
    m = metrics.CumulativeMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())

  def test_is_cumulative(self):
    m = metrics.CumulativeMetric('test', 'test', None)
    self.assertTrue(m.is_cumulative())


class FloatMetricTest(TestBase):

  def test_generate_proto(self):
    proto = self._test_proto(
        metrics.FloatMetric('test', 'test', None), lambda m: m.set(1.23),
        metrics_pb2.DOUBLE, metrics_pb2.GAUGE)
    self.assertAlmostEqual(1.23, proto.double_value)

  def test_set(self):
    m = metrics.FloatMetric('test', 'test', None)
    m.set(3.14)
    self.assertEquals(m.get(), 3.14)

  def test_non_number_raises(self):
    m = metrics.FloatMetric('test', 'test', None)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(object())

  def test_is_cumulative(self):
    m = metrics.FloatMetric('test', 'test', None)
    self.assertFalse(m.is_cumulative())


class DistributionMetricTest(TestBase):

  def _test_distribution_proto(self, dist):
    interface.register(dist)

    self.time_fn.return_value = 100.3
    for num in [0, 1, 5, 5.5, 9, 10, 10000]:
      dist.add(num)

    self.time_fn.return_value = 1000.6
    proto = list(interface._generate_proto())[0]
    data_set = proto.metrics_collection[0].metrics_data_set[0]
    data = data_set.data[0]

    self.assertAlmostEqual(1432.928571428, data.distribution_value.mean)
    self.assertEqual(metrics_pb2.DISTRIBUTION, data_set.value_type)
    self.assertEqual(100, data.start_timestamp.seconds)
    self.assertEqual(1000, data.end_timestamp.seconds)
    self.assertFalse(data_set.annotations.HasField('unit'))

    return data_set, data

  def test_generate_fixed_width_distribution(self):
    bucketer = distribution.FixedWidthBucketer(width=1, num_finite_buckets=10)
    dists = [
      (metrics.NonCumulativeDistributionMetric(
           'test0', 'test', None, bucketer=bucketer),
       metrics_pb2.GAUGE),
      (metrics.CumulativeDistributionMetric(
           'test1', 'test', None, bucketer=bucketer),
       metrics_pb2.CUMULATIVE)
    ]

    for dist, stream_kind in dists:
      data_set, data = self._test_distribution_proto(dist)

      self.assertListEqual([0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 1, 2],
                           list(data.distribution_value.bucket_count))
      self.assertEqual(
          10, data.distribution_value.linear_buckets.num_finite_buckets)
      self.assertEqual(1, data.distribution_value.linear_buckets.width)
      self.assertEqual(stream_kind, data_set.stream_kind)
      self.assertEqual(7, data.distribution_value.count)

  def test_generate_geometric_distribution(self):
    bucketer = distribution.GeometricBucketer(growth_factor=10**2,
                                              num_finite_buckets=10)
    dists = [
      (metrics.NonCumulativeDistributionMetric(
           'test0', 'test', None, bucketer=bucketer),
       metrics_pb2.GAUGE),
      (metrics.CumulativeDistributionMetric(
           'test1', 'test', None, bucketer=bucketer),
       metrics_pb2.CUMULATIVE)
    ]

    for dist, stream_kind in dists:
      data_set, data = self._test_distribution_proto(dist)

      self.assertListEqual([1, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
                           list(data.distribution_value.bucket_count))
      self.assertEqual(
          10, data.distribution_value.exponential_buckets.num_finite_buckets)
      self.assertEqual(
          10**2, data.distribution_value.exponential_buckets.growth_factor)
      self.assertEqual(stream_kind, data_set.stream_kind)
      self.assertEqual(7, data.distribution_value.count)

  def test_generate_geometric_distribution_with_scale(self):
    bucketer = distribution.GeometricBucketer(growth_factor=10.0,
                                              num_finite_buckets=10,
                                              scale=0.1)
    dists = [
      (metrics.NonCumulativeDistributionMetric(
           'test0', 'test', None, bucketer=bucketer),
       metrics_pb2.GAUGE),
      (metrics.CumulativeDistributionMetric(
           'test1', 'test', None, bucketer=bucketer),
       metrics_pb2.CUMULATIVE)
    ]

    for dist, stream_kind in dists:
      data_set, data = self._test_distribution_proto(dist)

      self.assertListEqual([1, 0, 4, 1, 0, 0, 1, 0, 0, 0, 0, 0],
                           list(data.distribution_value.bucket_count))
      self.assertEqual(
          10, data.distribution_value.exponential_buckets.num_finite_buckets)
      self.assertEqual(
          10.0, data.distribution_value.exponential_buckets.growth_factor)
      self.assertEqual(
          0.1, data.distribution_value.exponential_buckets.scale)
      self.assertEqual(stream_kind, data_set.stream_kind)
      self.assertEqual(7, data.distribution_value.count)

  def test_add(self):
    m = metrics.CumulativeDistributionMetric('test', 'test', None)
    m.add(1)
    m.add(10)
    m.add(100)
    self.assertEquals({1: 1, 5: 1, 10: 1}, m.get().buckets)
    self.assertEquals(111, m.get().sum)
    self.assertEquals(3, m.get().count)

  def test_add_custom_bucketer(self):
    m = metrics.CumulativeDistributionMetric('test', 'test', None,
        bucketer=distribution.FixedWidthBucketer(10))
    m.add(1)
    m.add(10)
    m.add(100)
    self.assertEquals({1: 1, 2: 1, 11: 1}, m.get().buckets)
    self.assertEquals(111, m.get().sum)
    self.assertEquals(3, m.get().count)

  def test_set(self):
    d = distribution.Distribution(
        distribution.FixedWidthBucketer(10, num_finite_buckets=10))
    d.add(1)
    d.add(10)
    d.add(100)

    m = metrics.CumulativeDistributionMetric('test', 'test', None)
    with self.assertRaises(TypeError):
      m.set(d)

    m = metrics.NonCumulativeDistributionMetric('test2', 'test', None)
    m.set(d)
    self.assertEquals(d, m.get())

    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set(1)
    with self.assertRaises(errors.MonitoringInvalidValueTypeError):
      m.set('foo')

  def test_is_cumulative(self):
    cd = metrics.CumulativeDistributionMetric('test', 'test', None)
    ncd = metrics.NonCumulativeDistributionMetric('test2', 'test', None)
    self.assertTrue(cd.is_cumulative())
    self.assertFalse(ncd.is_cumulative())
