# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed 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.

"""Metrics support manager."""

import logging
from buildtool import in_memory_metrics
from buildtool import prometheus_metrics
from buildtool import stackdriver_metrics
from buildtool.util import add_parser_argument


class MetricsManager(object):
  """Acts as factory for specialized BaseMetricsRegistry singleton."""

  __metrics_registry = None

  @staticmethod
  def singleton():
    """Returns the BaseMetricsRegistry once startup_metrics is called."""
    if MetricsManager.__metrics_registry is None:
      raise Exception('startup_metrics was not called.')
    return MetricsManager.__metrics_registry

  @staticmethod
  def init_argument_parser(parser, defaults):
    """Init argparser with metrics-related options."""
    in_memory_metrics.init_argument_parser(parser, defaults)
    prometheus_metrics.init_argument_parser(parser, defaults)
    stackdriver_metrics.init_argument_parser(parser, defaults)
    add_parser_argument(
        parser, 'metric_name_scope', defaults, 'buildtool',
        help='scope prefix for metrics generated by this tool')
    add_parser_argument(
        parser, 'monitoring_enabled', defaults, False, type=bool,
        help='Enable monitoring to stackdriver.')
    add_parser_argument(
        parser, 'monitoring_flush_frequency', defaults, 5,
        help='Frequency at which to push metrics in seconds.')
    add_parser_argument(
        parser, 'monitoring_system', defaults, 'file',
        choices=['file', 'prometheus', 'stackdriver'],
        help='Where to store metrics.')

  @staticmethod
  def startup_metrics(options):
    """Startup metrics module with concrete system."""
    monitoring_systems = {
        'file': in_memory_metrics.InMemoryMetricsRegistry,
        'prometheus': prometheus_metrics.PrometheusMetricsRegistry,
        'stackdriver': stackdriver_metrics.StackdriverMetricsRegistry
    }
    klas = monitoring_systems[options.monitoring_system]
    logging.info('Initializing monitoring with systme="%s"', klas.__name__)
    MetricsManager.__metrics_registry = klas(options)
    if options.monitoring_enabled and options.monitoring_flush_frequency > 0:
      MetricsManager.__metrics_registry.start_pusher_thread()
    return MetricsManager.__metrics_registry

  @staticmethod
  def shutdown_metrics():
    """Write final metrics out to metrics server."""
    registry = MetricsManager.singleton()
    registry.stop_pusher_thread()
    registry.flush_updated_metrics()
    registry.flush_final_metrics()

[((39, 4, 39, 60), 'buildtool.in_memory_metrics.init_argument_parser', 'in_memory_metrics.init_argument_parser', ({(39, 43, 39, 49): 'parser', (39, 51, 39, 59): 'defaults'}, {}), '(parser, defaults)', False, 'from buildtool import in_memory_metrics\n'), ((40, 4, 40, 61), 'buildtool.prometheus_metrics.init_argument_parser', 'prometheus_metrics.init_argument_parser', ({(40, 44, 40, 50): 'parser', (40, 52, 40, 60): 'defaults'}, {}), '(parser, defaults)', False, 'from buildtool import prometheus_metrics\n'), ((41, 4, 41, 62), 'buildtool.stackdriver_metrics.init_argument_parser', 'stackdriver_metrics.init_argument_parser', ({(41, 45, 41, 51): 'parser', (41, 53, 41, 61): 'defaults'}, {}), '(parser, defaults)', False, 'from buildtool import stackdriver_metrics\n'), ((42, 4, 44, 63), 'buildtool.util.add_parser_argument', 'add_parser_argument', (), '', False, 'from buildtool.util import add_parser_argument\n'), ((45, 4, 47, 49), 'buildtool.util.add_parser_argument', 'add_parser_argument', (), '', False, 'from buildtool.util import add_parser_argument\n'), ((48, 4, 50, 62), 'buildtool.util.add_parser_argument', 'add_parser_argument', (), '', False, 'from buildtool.util import add_parser_argument\n'), ((51, 4, 54, 39), 'buildtool.util.add_parser_argument', 'add_parser_argument', (), '', False, 'from buildtool.util import add_parser_argument\n'), ((65, 4, 65, 75), 'logging.info', 'logging.info', ({(65, 17, 65, 59): '"""Initializing monitoring with systme="%s\\""""', (65, 61, 65, 74): 'klas.__name__'}, {}), '(\'Initializing monitoring with systme="%s"\', klas.__name__)', False, 'import logging\n')]