# Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from .result import SKIPPED


"""
Pipeline

Test processors are chained together and communicate with each other by
calling previous/next processor in the chain.
     ----next_test()---->     ----next_test()---->
Proc1                    Proc2                    Proc3
     <---result_for()----     <---result_for()----

For every next_test there is exactly one result_for call.
If processor ignores the test it has to return SkippedResult.
If it created multiple subtests for one test and wants to pass all of them to
the previous processor it can enclose them in GroupedResult.


Subtests

When test processor needs to modify the test or create some variants of the
test it creates subtests and sends them to the next processor.
Each subtest has:
- procid - globally unique id that should contain id of the parent test and
          some suffix given by test processor, e.g. its name + subtest type.
- processor - which created it
- origin - pointer to the parent (sub)test
"""


DROP_RESULT = 0
DROP_OUTPUT = 1
DROP_PASS_OUTPUT = 2
DROP_PASS_STDOUT = 3

def get_reduce_result_function(requirement):
  if requirement == DROP_RESULT:
    return lambda _: None

  if requirement == DROP_OUTPUT:
    def f(result):
      result.output = None
      return result
    return f

  if requirement == DROP_PASS_OUTPUT:
    def f(result):
      if not result.has_unexpected_output:
        result.output = None
      return result
    return f

  if requirement == DROP_PASS_STDOUT:
    def f(result):
      if not result.has_unexpected_output:
        result.output.stdout = None
        result.output.stderr = None
      return result
    return f


class TestProc(object):
  def __init__(self):
    self._prev_proc = None
    self._next_proc = None
    self._requirement = DROP_RESULT
    self._prev_requirement = None
    self._reduce_result = lambda result: result

  def connect_to(self, next_proc):
    """Puts `next_proc` after itself in the chain."""
    next_proc._prev_proc = self
    self._next_proc = next_proc

  def remove_from_chain(self):
    if self._prev_proc:
      self._prev_proc._next_proc = self._next_proc
    if self._next_proc:
      self._next_proc._prev_proc = self._prev_proc

  def setup(self, requirement=DROP_RESULT):
    """
    Method called by previous processor or processor pipeline creator to let
    the processors know what part of the result can be ignored.
    """
    self._prev_requirement = requirement
    if self._next_proc:
      self._next_proc.setup(max(requirement, self._requirement))
    if self._prev_requirement < self._requirement:
      self._reduce_result = get_reduce_result_function(self._prev_requirement)

  def next_test(self, test):
    """
    Method called by previous processor whenever it produces new test.
    This method shouldn't be called by anyone except previous processor.
    """
    raise NotImplementedError()

  def result_for(self, test, result):
    """
    Method called by next processor whenever it has result for some test.
    This method shouldn't be called by anyone except next processor.
    """
    raise NotImplementedError()

  def heartbeat(self):
    if self._prev_proc:
      self._prev_proc.heartbeat()

  ### Communication

  def _send_test(self, test):
    """Helper method for sending test to the next processor."""
    self._next_proc.next_test(test)

  def _send_result(self, test, result):
    """Helper method for sending result to the previous processor."""
    result = self._reduce_result(result)
    self._prev_proc.result_for(test, result)



class TestProcObserver(TestProc):
  """Processor used for observing the data."""
  def __init__(self):
    super(TestProcObserver, self).__init__()

  def next_test(self, test):
    self._on_next_test(test)
    self._send_test(test)

  def result_for(self, test, result):
    self._on_result_for(test, result)
    self._send_result(test, result)

  def heartbeat(self):
    self._on_heartbeat()
    super(TestProcObserver, self).heartbeat()

  def _on_next_test(self, test):
    """Method called after receiving test from previous processor but before
    sending it to the next one."""
    pass

  def _on_result_for(self, test, result):
    """Method called after receiving result from next processor but before
    sending it to the previous one."""
    pass

  def _on_heartbeat(self):
    pass


class TestProcProducer(TestProc):
  """Processor for creating subtests."""

  def __init__(self, name):
    super(TestProcProducer, self).__init__()
    self._name = name

  def next_test(self, test):
    self._next_test(test)

  def result_for(self, subtest, result):
    self._result_for(subtest.origin, subtest, result)

  ### Implementation
  def _next_test(self, test):
    raise NotImplementedError()

  def _result_for(self, test, subtest, result):
    """
    result_for method extended with `subtest` parameter.

    Args
      test: test used by current processor to create the subtest.
      subtest: test for which the `result` is.
      result: subtest execution result created by the output processor.
    """
    raise NotImplementedError()

  ### Managing subtests
  def _create_subtest(self, test, subtest_id, **kwargs):
    """Creates subtest with subtest id <processor name>-`subtest_id`."""
    return test.create_subtest(self, '%s-%s' % (self._name, subtest_id),
                               **kwargs)


class TestProcFilter(TestProc):
  """Processor for filtering tests."""

  def next_test(self, test):
    if self._filter(test):
      self._send_result(test, SKIPPED)
    else:
      self._send_test(test)

  def result_for(self, test, result):
    self._send_result(test, result)

  def _filter(self, test):
    """Returns whether test should be filtered out."""
    raise NotImplementedError()
