#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
The classes in this file are interfaces for metrics. They are not intended
to be subclassed or created directly by users. To work with and access metrics,
users should use the classes and methods exposed in metric.py.

Available classes:

- Metric - Base interface of a metrics object.
- Counter - Counter metric interface. Allows a count to be incremented or
    decremented during pipeline execution.
- Distribution - Distribution Metric interface. Allows statistics about the
    distribution of a variable to be collected during pipeline execution.
- Gauge - Gauge Metric interface. Allows to track the latest value of a
    variable during pipeline execution.
- MetricName - Namespace and name used to refer to a Metric.
"""

# pytype: skip-file

from typing import Dict
from typing import Optional

__all__ = [
    'Metric',
    'Counter',
    'Distribution',
    'Gauge',
    'StringSet',
    'BoundedTrie',
    'Histogram',
    'MetricName'
]


class MetricName(object):
  """The name of a metric.

  The name of a metric consists of a namespace and a name. The namespace
  allows grouping related metrics together and also prevents collisions
  between multiple metrics of the same name.
  """
  def __init__(
      self,
      namespace: Optional[str],
      name: Optional[str],
      urn: Optional[str] = None,
      labels: Optional[Dict[str, str]] = None) -> None:
    """Initializes ``MetricName``.

    Note: namespace and name should be set for user metrics,
    urn and labels should be set for an arbitrary metric to package into a
    MonitoringInfo.

    Args:
      namespace: A string with the namespace of a metric.
      name: A string with the name of a metric.
      urn: URN to populate on a MonitoringInfo, when sending to RunnerHarness.
      labels: Labels to populate on a MonitoringInfo
    """
    if not urn:
      if not namespace:
        raise ValueError('Metric namespace must be non-empty')
      if not name:
        raise ValueError('Metric name must be non-empty')
    self.namespace = namespace
    self.name = name
    self.urn = urn
    self.labels = labels if labels else {}

  def __eq__(self, other):
    return (
        self.namespace == other.namespace and self.name == other.name and
        self.urn == other.urn and self.labels == other.labels)

  def __str__(self):
    if self.urn:
      return 'MetricName(namespace={}, name={}, urn={}, labels={})'.format(
          self.namespace, self.name, self.urn, self.labels)
    else:  # User counter case.
      return 'MetricName(namespace={}, name={})'.format(
          self.namespace, self.name)

  def __hash__(self):
    return hash((self.namespace, self.name, self.urn) +
                tuple(self.labels.items()))

  def fast_name(self):
    name = self.name or ''
    namespace = self.namespace or ''
    urn = self.urn or ''
    labels = ''
    if self.labels:
      labels = '_'.join(['%s=%s' % (k, v) for (k, v) in self.labels.items()])
    return '%d_%s%s%s%s' % (len(name), name, namespace, urn, labels)


class Metric(object):
  """Base interface of a metric object."""
  def __init__(self, metric_name: MetricName) -> None:
    self.metric_name = metric_name


class Counter(Metric):
  """Counter metric interface. Allows a count to be incremented/decremented
  during pipeline execution."""
  def inc(self, n=1):
    raise NotImplementedError

  def dec(self, n=1):
    self.inc(-n)


class Distribution(Metric):
  """Distribution Metric interface.

  Allows statistics about the distribution of a variable to be collected during
  pipeline execution."""
  def update(self, value):
    raise NotImplementedError


class Gauge(Metric):
  """Gauge Metric interface.

  Allows tracking of the latest value of a variable during pipeline
  execution."""
  def set(self, value):
    raise NotImplementedError


class StringSet(Metric):
  """StringSet Metric interface.

  Reports set of unique string values during pipeline execution.."""
  def add(self, value):
    raise NotImplementedError


class BoundedTrie(Metric):
  """BoundedTrie Metric interface.

  Reports set of unique string values during pipeline execution.."""
  def add(self, value):
    raise NotImplementedError


class Histogram(Metric):
  """Histogram Metric interface.

  Allows statistics about the percentile of a variable to be collected during
  pipeline execution."""
  def update(self, value):
    raise NotImplementedError
