# Copyright 2015 gRPC authors.
#
# 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.
"""Code for making a service.TestService more amenable to use in tests."""

import collections
import threading

import six

# test_control, _service, and test_interfaces are referenced from specification
# in this module.
from grpc.framework.common import cardinality
from grpc.framework.common import style
from grpc.framework.foundation import stream
from grpc.framework.foundation import stream_util
from grpc.framework.interfaces.face import face
from tests.unit.framework.common import test_control  # pylint: disable=unused-import
from tests.unit.framework.interfaces.face import _service  # pylint: disable=unused-import
from tests.unit.framework.interfaces.face import test_interfaces  # pylint: disable=unused-import

_IDENTITY = lambda x: x


class TestServiceDigest(
        collections.namedtuple('TestServiceDigest', (
            'methods', 'inline_method_implementations',
            'event_method_implementations', 'multi_method_implementation',
            'unary_unary_messages_sequences', 'unary_stream_messages_sequences',
            'stream_unary_messages_sequences',
            'stream_stream_messages_sequences',))):
    """A transformation of a service.TestService.

  Attributes:
    methods: A dict from method group-name pair to test_interfaces.Method object
      describing the RPC methods that may be called during the test.
    inline_method_implementations: A dict from method group-name pair to
      face.MethodImplementation object to be used in tests of in-line calls to
      behaviors under test.
    event_method_implementations: A dict from method group-name pair to
      face.MethodImplementation object to be used in tests of event-driven calls
      to behaviors under test.
    multi_method_implementation: A face.MultiMethodImplementation to be used in
      tests of generic calls to behaviors under test.
    unary_unary_messages_sequences: A dict from method group-name pair to
      sequence of service.UnaryUnaryTestMessages objects to be used to test the
      identified method.
    unary_stream_messages_sequences: A dict from method group-name pair to
      sequence of service.UnaryStreamTestMessages objects to be used to test the
      identified method.
    stream_unary_messages_sequences: A dict from method group-name pair to
      sequence of service.StreamUnaryTestMessages objects to be used to test the
      identified method.
    stream_stream_messages_sequences: A dict from method group-name pair to
      sequence of service.StreamStreamTestMessages objects to be used to test