//
// DO NOT EDIT.
//
// Generated by the protocol buffer compiler.
// Source: echo.proto
//

//
// Copyright 2018, gRPC Authors All rights reserved.
//
// 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.
//
import SwiftGRPC
import NIO
import SwiftProtobuf


/// Usage: instantiate `Echo_EchoClient`, then call methods of this protocol to make API calls.
public protocol Echo_EchoClientProtocol: GRPCClient {
  var serviceName: String { get }
  var interceptors: Echo_EchoClientInterceptorFactoryProtocol? { get }

  func get(
    _ request: Echo_EchoRequest,
    callOptions: CallOptions?
  ) -> UnaryCall<Echo_EchoRequest, Echo_EchoResponse>

  func expand(
    _ request: Echo_EchoRequest,
    callOptions: CallOptions?,
    handler: @escaping (Echo_EchoResponse) -> Void
  ) -> ServerStreamingCall<Echo_EchoRequest, Echo_EchoResponse>

  func collect(
    callOptions: CallOptions?
  ) -> ClientStreamingCall<Echo_EchoRequest, Echo_EchoResponse>

  func update(
    callOptions: CallOptions?,
    handler: @escaping (Echo_EchoResponse) -> Void
  ) -> BidirectionalStreamingCall<Echo_EchoRequest, Echo_EchoResponse>
}

extension Echo_EchoClientProtocol {
  public var serviceName: String {
    return "echo.Echo"
  }

  /// Immediately returns an echo of a request.
  ///
  /// - Parameters:
  ///   - request: Request to send to Get.
  ///   - callOptions: Call options.
  /// - Returns: A `UnaryCall` with futures for the metadata, status and response.
  public func get(
    _ request: Echo_EchoRequest,
    callOptions: CallOptions? = nil
  ) -> UnaryCall<Echo_EchoRequest, Echo_EchoResponse> {
    return self.makeUnaryCall(
      path: "/echo.Echo/Get",
      request: request,
      callOptions: callOptions ?? self.defaultCallOptions,
      interceptors: self.interceptors?.makeGetInterceptors() ?? []
    )
  }

  /// Splits a request into words and returns each word in a stream of messages.
  ///
  /// - Parameters:
  ///   - request: Request to send to Expand.
  ///   - callOptions: Call options.
  ///   - handler: A closure called when each response is received from the server.
  /// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
  public func expand(
    _ request: Echo_EchoRequest,
    callOptions: CallOptions? = nil,
    handler: @escaping (Echo_EchoResponse) -> Void
  ) -> ServerStreamingCall<Echo_EchoRequest, Echo_EchoResponse> {
    return self.makeServerStreamingCall(
      path: "/echo.Echo/Expand",
      request: request,
      callOptions: callOptions ?? self.defaultCallOptions,
      interceptors: self.interceptors?.makeExpandInterceptors() ?? [],
      handler: handler
    )
  }

  /// Collects a stream of messages and returns them concatenated when the caller closes.
  ///
  /// Callers should use the `send` method on the returned object to send messages
  /// to the server. The caller should send an `.end` after the final message has been sent.
  ///
  /// - Parameters:
  ///   - callOptions: Call options.
  /// - Returns: A `ClientStreamingCall` with futures for the metadata, status and response.
  public func collect(
    callOptions: CallOptions? = nil
  ) -> ClientStreamingCall<Echo_EchoRequest, Echo_EchoResponse> {
    return self.makeClientStreamingCall(
      path: "/echo.Echo/Collect",
      callOptions: callOptions ?? self.defaultCallOptions,
      interceptors: self.interceptors?.makeCollectInterceptors() ?? []
    )
  }

  /// Streams back messages as they are received in an input stream.
  ///
  /// Callers should use the `send` method on the returned object to send messages
  /// to the server. The caller should send an `.end` after the final message has been sent.
  ///
  /// - Parameters:
  ///   - callOptions: Call options.
  ///   - handler: A closure called when each response is received from the server.
  /// - Returns: A `ClientStreamingCall` with futures for the metadata and status.
  public func update(
    callOptions: CallOptions? = nil,
    handler: @escaping (Echo_EchoResponse) -> Void
  ) -> BidirectionalStreamingCall<Echo_EchoRequest, Echo_EchoResponse> {
    return self.makeBidirectionalStreamingCall(
      path: "/echo.Echo/Update",
      callOptions: callOptions ?? self.defaultCallOptions,
      interceptors: self.interceptors?.makeUpdateInterceptors() ?? [],
      handler: handler
    )
  }
}

public protocol Echo_EchoClientInterceptorFactoryProtocol {

  /// - Returns: Interceptors to use when invoking 'get'.
  func makeGetInterceptors() -> [ClientInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when invoking 'expand'.
  func makeExpandInterceptors() -> [ClientInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when invoking 'collect'.
  func makeCollectInterceptors() -> [ClientInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when invoking 'update'.
  func makeUpdateInterceptors() -> [ClientInterceptor<Echo_EchoRequest, Echo_EchoResponse>]
}

public final class Echo_EchoClient: Echo_EchoClientProtocol {
  public let channel: GRPCChannel
  public var defaultCallOptions: CallOptions
  public var interceptors: Echo_EchoClientInterceptorFactoryProtocol?

  /// Creates a client for the echo.Echo service.
  ///
  /// - Parameters:
  ///   - channel: `GRPCChannel` to the service host.
  ///   - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
  ///   - interceptors: A factory providing interceptors for each RPC.
  public init(
    channel: GRPCChannel,
    defaultCallOptions: CallOptions = CallOptions(),
    interceptors: Echo_EchoClientInterceptorFactoryProtocol? = nil
  ) {
    self.channel = channel
    self.defaultCallOptions = defaultCallOptions
    self.interceptors = interceptors
  }
}

public final class Echo_EchoTestClient: Echo_EchoClientProtocol {
  private let fakeChannel: FakeChannel
  public var defaultCallOptions: CallOptions
  public var interceptors: Echo_EchoClientInterceptorFactoryProtocol?

  public var channel: GRPCChannel {
    return self.fakeChannel
  }

  public init(
    fakeChannel: FakeChannel = FakeChannel(),
    defaultCallOptions callOptions: CallOptions = CallOptions(),
    interceptors: Echo_EchoClientInterceptorFactoryProtocol? = nil
  ) {
    self.fakeChannel = fakeChannel
    self.defaultCallOptions = callOptions
    self.interceptors = interceptors
  }

  /// Make a unary response for the Get RPC. This must be called
  /// before calling 'get'. See also 'FakeUnaryResponse'.
  ///
  /// - Parameter requestHandler: a handler for request parts sent by the RPC.
  public func makeGetResponseStream(
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  ) -> FakeUnaryResponse<Echo_EchoRequest, Echo_EchoResponse> {
    return self.fakeChannel.makeFakeUnaryResponse(path: "/echo.Echo/Get", requestHandler: requestHandler)
  }

  public func enqueueGetResponse(
    _ response: Echo_EchoResponse,
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  )  {
    let stream = self.makeGetResponseStream(requestHandler)
    // This is the only operation on the stream; try! is fine.
    try! stream.sendMessage(response)
  }

  /// Returns true if there are response streams enqueued for 'Get'
  public var hasGetResponsesRemaining: Bool {
    return self.fakeChannel.hasFakeResponseEnqueued(forPath: "/echo.Echo/Get")
  }

  /// Make a streaming response for the Expand RPC. This must be called
  /// before calling 'expand'. See also 'FakeStreamingResponse'.
  ///
  /// - Parameter requestHandler: a handler for request parts sent by the RPC.
  public func makeExpandResponseStream(
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  ) -> FakeStreamingResponse<Echo_EchoRequest, Echo_EchoResponse> {
    return self.fakeChannel.makeFakeStreamingResponse(path: "/echo.Echo/Expand", requestHandler: requestHandler)
  }

  public func enqueueExpandResponses(
    _ responses: [Echo_EchoResponse],
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  )  {
    let stream = self.makeExpandResponseStream(requestHandler)
    // These are the only operation on the stream; try! is fine.
    responses.forEach { try! stream.sendMessage($0) }
    try! stream.sendEnd()
  }

  /// Returns true if there are response streams enqueued for 'Expand'
  public var hasExpandResponsesRemaining: Bool {
    return self.fakeChannel.hasFakeResponseEnqueued(forPath: "/echo.Echo/Expand")
  }

  /// Make a unary response for the Collect RPC. This must be called
  /// before calling 'collect'. See also 'FakeUnaryResponse'.
  ///
  /// - Parameter requestHandler: a handler for request parts sent by the RPC.
  public func makeCollectResponseStream(
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  ) -> FakeUnaryResponse<Echo_EchoRequest, Echo_EchoResponse> {
    return self.fakeChannel.makeFakeUnaryResponse(path: "/echo.Echo/Collect", requestHandler: requestHandler)
  }

  public func enqueueCollectResponse(
    _ response: Echo_EchoResponse,
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  )  {
    let stream = self.makeCollectResponseStream(requestHandler)
    // This is the only operation on the stream; try! is fine.
    try! stream.sendMessage(response)
  }

  /// Returns true if there are response streams enqueued for 'Collect'
  public var hasCollectResponsesRemaining: Bool {
    return self.fakeChannel.hasFakeResponseEnqueued(forPath: "/echo.Echo/Collect")
  }

  /// Make a streaming response for the Update RPC. This must be called
  /// before calling 'update'. See also 'FakeStreamingResponse'.
  ///
  /// - Parameter requestHandler: a handler for request parts sent by the RPC.
  public func makeUpdateResponseStream(
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  ) -> FakeStreamingResponse<Echo_EchoRequest, Echo_EchoResponse> {
    return self.fakeChannel.makeFakeStreamingResponse(path: "/echo.Echo/Update", requestHandler: requestHandler)
  }

  public func enqueueUpdateResponses(
    _ responses: [Echo_EchoResponse],
    _ requestHandler: @escaping (FakeRequestPart<Echo_EchoRequest>) -> () = { _ in }
  )  {
    let stream = self.makeUpdateResponseStream(requestHandler)
    // These are the only operation on the stream; try! is fine.
    responses.forEach { try! stream.sendMessage($0) }
    try! stream.sendEnd()
  }

  /// Returns true if there are response streams enqueued for 'Update'
  public var hasUpdateResponsesRemaining: Bool {
    return self.fakeChannel.hasFakeResponseEnqueued(forPath: "/echo.Echo/Update")
  }
}

/// To build a server, implement a class that conforms to this protocol.
public protocol Echo_EchoProvider: CallHandlerProvider {
  var interceptors: Echo_EchoServerInterceptorFactoryProtocol? { get }

  /// Immediately returns an echo of a request.
  func get(request: Echo_EchoRequest, context: StatusOnlyCallContext) -> EventLoopFuture<Echo_EchoResponse>

  /// Splits a request into words and returns each word in a stream of messages.
  func expand(request: Echo_EchoRequest, context: StreamingResponseCallContext<Echo_EchoResponse>) -> EventLoopFuture<GRPCStatus>

  /// Collects a stream of messages and returns them concatenated when the caller closes.
  func collect(context: UnaryResponseCallContext<Echo_EchoResponse>) -> EventLoopFuture<(StreamEvent<Echo_EchoRequest>) -> Void>

  /// Streams back messages as they are received in an input stream.
  func update(context: StreamingResponseCallContext<Echo_EchoResponse>) -> EventLoopFuture<(StreamEvent<Echo_EchoRequest>) -> Void>
}

extension Echo_EchoProvider {
  public var serviceName: Substring { return "echo.Echo" }

  /// Determines, calls and returns the appropriate request handler, depending on the request's method.
  /// Returns nil for methods not handled by this service.
  public func handle(
    method name: Substring,
    context: CallHandlerContext
  ) -> GRPCServerHandlerProtocol? {
    switch name {
    case "Get":
      return UnaryServerHandler(
        context: context,
        requestDeserializer: ProtobufDeserializer<Echo_EchoRequest>(),
        responseSerializer: ProtobufSerializer<Echo_EchoResponse>(),
        interceptors: self.interceptors?.makeGetInterceptors() ?? [],
        userFunction: self.get(request:context:)
      )

    case "Expand":
      return ServerStreamingServerHandler(
        context: context,
        requestDeserializer: ProtobufDeserializer<Echo_EchoRequest>(),
        responseSerializer: ProtobufSerializer<Echo_EchoResponse>(),
        interceptors: self.interceptors?.makeExpandInterceptors() ?? [],
        userFunction: self.expand(request:context:)
      )

    case "Collect":
      return ClientStreamingServerHandler(
        context: context,
        requestDeserializer: ProtobufDeserializer<Echo_EchoRequest>(),
        responseSerializer: ProtobufSerializer<Echo_EchoResponse>(),
        interceptors: self.interceptors?.makeCollectInterceptors() ?? [],
        observerFactory: self.collect(context:)
      )

    case "Update":
      return BidirectionalStreamingServerHandler(
        context: context,
        requestDeserializer: ProtobufDeserializer<Echo_EchoRequest>(),
        responseSerializer: ProtobufSerializer<Echo_EchoResponse>(),
        interceptors: self.interceptors?.makeUpdateInterceptors() ?? [],
        observerFactory: self.update(context:)
      )

    default:
      return nil
    }
  }
}

public protocol Echo_EchoServerInterceptorFactoryProtocol {

  /// - Returns: Interceptors to use when handling 'get'.
  ///   Defaults to calling `self.makeInterceptors()`.
  func makeGetInterceptors() -> [ServerInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when handling 'expand'.
  ///   Defaults to calling `self.makeInterceptors()`.
  func makeExpandInterceptors() -> [ServerInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when handling 'collect'.
  ///   Defaults to calling `self.makeInterceptors()`.
  func makeCollectInterceptors() -> [ServerInterceptor<Echo_EchoRequest, Echo_EchoResponse>]

  /// - Returns: Interceptors to use when handling 'update'.
  ///   Defaults to calling `self.makeInterceptors()`.
  func makeUpdateInterceptors() -> [ServerInterceptor<Echo_EchoRequest, Echo_EchoResponse>]
}
