#!/usr/bin/env python
# -*- 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.

"""mock_generator.py: module for creating mock objects for unittesting
                      mainly for common/tests/python/utils"""

# pylint: disable=unused-argument
# pylint: disable=missing-docstring
import random
from mock import patch

from heronpy.api.task_hook import ITaskHook
from heronpy.api.custom_grouping import ICustomGrouping
from heronpy.api.serializer import PythonSerializer
from heron.instance.src.python.utils.metrics import MetricsCollector
from heron.instance.src.python.utils.misc import (OutgoingTupleHelper, PhysicalPlanHelper,
                                                HeronCommunicator)
from heron.proto import tuple_pb2

import heron.instance.src.python.utils.system_constants as constants
import heron.instance.tests.python.mock_protobuf as mock_protobuf

prim_list = [1000, -234, 0.00023, "string",
             ["abc", "def", "ghi"], True, False,
             ("tuple", 123, True), None, {}]

# Returns legit looking topology
def get_a_sample_pplan():
  """Returns a legitimate looking physical plan

  This topology has 1 spout and 2 bolts. Currently no input/output streams.
  There is only one stream manager.

  [Instance 1: spout1]
    - instance_id = "instance1"
    - task_id = 100
    - component_index = 0
    - component_name = "spout1"

  [Instance 2: bolt1]
    - instance_id = "instance2"
    - task_id = 200
    - component_index = 0
    - component_name = "bolt1"

  [instance 3: bolt2]
    - instance_id = "instance3"
    - task_id = 300
    - component_index = 0
    - component_name = "bolt2"

  :returns: PhysicalPlan message and a list of dictionaries for each instance containing
            (instance_id, task_id, comp_index, comp_name)
  """

  spout_1 = mock_protobuf.get_mock_spout(component=mock_protobuf.get_mock_component(name="spout1"))
  bolt_1 = mock_protobuf.get_mock_bolt(component=mock_protobuf.get_mock_component(name="bolt1"))
  bolt_2 = mock_protobuf.get_mock_bolt(component=mock_protobuf.get_mock_component(name="bolt2"))

  topology = mock_protobuf.get_mock_topology(spouts=[spout_1], bolts=[bolt_1, bolt_2])


  instance_ids = ["instance1", "instance2", "instancer3"]
  task_ids = [100, 200, 300]
  comp_indexes = [0, 0, 0]
  comp_names = ["spout1", "bolt1", "bolt2"]
  instances = []

  for i_id, t_id, c_i, c_name in zip(instance_ids, task_ids, comp_indexes, comp_names):
    info = mock_protobuf.get_mock_instance_info(task_id=t_id,
                                                component_index=c_i,
                                                component_name=c_name)
    instance = mock_protobuf.get_mock_instance(instance_id=i_id, info=info)
    instances.append(instance)

  pplan = mock_protobuf.get_mock_pplan(topology=topology, instances=instances)

  keys = ["instance_id", "task_id", "comp_index", "comp_name"]
  zipped = list(zip(instance_ids, task_ids, comp_indexes, comp_names))
  return pplan, [dict(list(zip(keys, z))) for z in zipped]

def make_data_tuple_from_list(lst, serializer=PythonSerializer()):
  """Make HeronDataTuple from a list of objects"""
  data_tuple = tuple_pb2.HeronDataTuple()
  data_tuple.key = 0

  tuple_size_in_bytes = 0

  for obj in lst:
    serialized = serializer.serialize(obj)
    data_tuple.values.append(serialized)
    tuple_size_in_bytes += len(serialized)
  return data_tuple, tuple_size_in_bytes

class MockOutgoingTupleHelper(OutgoingTupleHelper):
  """Creates a mock OutgoingTupleHelper class, for unittesting"""
  SAMPLE_SUCCESS = 0
  def __init__(self, mode=SAMPLE_SUCCESS):
    self.called_init_new_data = False
    self.called_init_new_control = False
    sample_sys_config = {constants.INSTANCE_SET_DATA_TUPLE_CAPACITY: 1000,
                         constants.INSTANCE_SET_DATA_TUPLE_SIZE_BYTES: 2000,
                         constants.INSTANCE_SET_CONTROL_TUPLE_CAPACITY: 3000}

    if mode == MockOutgoingTupleHelper.SAMPLE_SUCCESS:
      pplan_helper, out_stream = self._prepare_sample_success()
      with patch("heron.instance.src.python.utils.system_config.get_sys_config",
                 side_effect=lambda: sample_sys_config):
        super(MockOutgoingTupleHelper, self).__init__(pplan_helper, out_stream)

  @staticmethod
  def _prepare_sample_success():
    pplan, instances = get_a_sample_pplan()
    pplan_helper = PhysicalPlanHelper(pplan, instances[0]["instance_id"], "topology.pex.path")
    out_stream = HeronCommunicator(producer_cb=None, consumer_cb=None)
    return pplan_helper, out_stream

  def _init_new_data_tuple(self, stream_id):
    self.called_init_new_data = True
    OutgoingTupleHelper._init_new_data_tuple(self, stream_id)

  def _init_new_control_tuple(self):
    self.called_init_new_control = True
    OutgoingTupleHelper._init_new_control_tuple(self)

class MockMetricsCollector(MetricsCollector):
  """Creates a mock MetricsCollector class, for unittesting"""
  def __init__(self):
    self.registered_timers = []
    super(MockMetricsCollector, self).__init__(None, HeronCommunicator())

  def _register_timer_task(self, time_bucket_in_sec):
    self.registered_timers.append(time_bucket_in_sec)

class MockCustomGrouping(ICustomGrouping):
  ALL_TARGET_MODE = 0   # returns the whole list of target tasks
  RANDOM_TARGET_MODE = 1
  WRONG_RETURN_TYPE_MODE = 2
  WRONG_CHOOSE_TASK_MODE = 3

  def __init__(self, mode):
    super(MockCustomGrouping, self).__init__()
    self.mode = mode

  def prepare(self, context, component, stream, target_tasks):
    self.target_tasks = target_tasks

  def choose_tasks(self, values):
    if self.mode == self.ALL_TARGET_MODE:
      return self.target_tasks
    elif self.mode == self.RANDOM_TARGET_MODE:
      return [task for task in self.target_tasks if bool(random.getrandbits(1))]
    elif self.mode == self.WRONG_RETURN_TYPE_MODE:
      return 'string'
    elif self.mode == self.WRONG_CHOOSE_TASK_MODE:
      ret = []
      while len(ret) < 5:
        i = random.randint(1, 1000)
        if i not in self.target_tasks and i not in ret:
          ret.append(i)
        else:
          continue
      return ret

class MockTaskHook(ITaskHook):
  def prepare(self, conf, context):
    self.clean_up_called = False
    self.emit_called = False
    self.spout_ack_called = False
    self.spout_fail_called = False
    self.bolt_exec_called = False
    self.bolt_ack_called = False
    self.bolt_fail_called = False

  def emit(self, emit_info):
    self.emit_called = True

  def spout_ack(self, spout_ack_info):
    self.spout_ack_called = True

  def spout_fail(self, spout_fail_info):
    self.spout_fail_called = True

  def bolt_execute(self, bolt_execute_info):
    self.bolt_exec_called = True

  def bolt_ack(self, bolt_ack_info):
    self.bolt_ack_called = True

  def bolt_fail(self, bolt_fail_info):
    self.bolt_fail_called = True
