# Protocol imports
from google.protobuf.timestamp_pb2 import Timestamp

from .common_pb2 import Request, Response


async def native_grpc_call(
    metadata, full_method_name, method_desc, request, classes, channel
):
    """
    Calls the provided gRPC method by invoking it directly on the channel.
    """
    # Get the classes for request and response, needed to deserialize
    # and serialize messages from the channel correctly
    req_class, rep_class = classes

    if method_desc.server_streaming:
        # Server-streaming call
        call = channel.unary_stream(
            full_method_name,
            request_serializer=req_class.SerializeToString,
            response_deserializer=rep_class.FromString,
        )
        responses = []
        # In this case, call responds with a wrapper that is an async
        # generator function
        async for resp in call(request, metadata=metadata):
            responses.append(resp)
        return responses[-1]  # Just the last response is needed
    else:
        # Unary call
        call = channel.unary_unary(
            full_method_name,
            request_serializer=req_class.SerializeToString,
            response_deserializer=rep_class.FromString,
        )
        return await call(request, metadata=metadata)


def generate_request():
    """
    Generates a protobuf request object for an RPC given a
    sender ID.
    """
    return Request(timestamp=Timestamp().GetCurrentTime())


def generate_response(resp_type, resp_string=""):
    """
    Generates a protobuf response object for an RPC given a
    response type and optional response string.
    """
    return Response(
        status=resp_type,
        response_string=resp_string,
        timestamp=Timestamp().GetCurrentTime(),
    )
