#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

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

'''topology_context.py'''
from abc import abstractmethod

class TopologyContext:
  """Topology Context is the means for spouts/bolts to get information about
     the running topology. This file just is the interface to be used by spouts/bolts

  This is automatically created by Heron Instance and topology writers never need to create
  an instance by themselves.
  """
  @abstractmethod
  def get_task_id(self):
    """Gets the task id of this component
    :return: the task_id of this component
    """

  @abstractmethod
  def get_component_id(self):
    """Gets the component id of this component
    :return: the component_id of this component
    """

  @abstractmethod
  def get_cluster_config(self):
    """Returns the cluster config for this component
    Note that the returned config is auto-typed map: <str -> any Python object>.
    :return: the dict of key -> value
    """

  @abstractmethod
  def get_topology_name(self):
    """Returns the name of the topology
    :return: the name of the topology
    """

  @abstractmethod
  def register_metric(self, name, metric, time_bucket_in_sec):
    """Registers a new metric to this context
    :param name: The name of the metric
    :param metric: The IMetric that needs to be registered
    :param time_bucket_in_sec: The interval in seconds to do getValueAndReset
    """

  @abstractmethod
  def get_sources(self, component_id):
    """Returns the declared inputs to specified component
    :param component_id: The name of the component whose inputs we want

    :return: map <streamId namedtuple (same structure as protobuf msg) -> gtype>, or
             None if not found
    """

  def get_this_sources(self):
    """Returns the declared inputs to this component
    :return: map <streamId namedtuple (same structure as protobuf msg) -> gtype>, or
             None if not found
    """
    return self.get_sources(self.get_component_id())

  @abstractmethod
  def get_component_tasks(self, component_id):
    """Returns the task ids allocated for the given component id
    :param component_id: The name of the component whose task ids we want

    :return: list of task_ids or None if not found
    """

  @abstractmethod
  def add_task_hook(self, task_hook):
    """Registers a specified task hook to this context

    :type task_hook: ITaskHook
    :param task_hook: Implementation of ITaskHook
    """
