#include <chrono>
#include <string_view>
#include <utility>
 
#include <fmt/format.h>
 
 
 
#include <samples/greeter_client.usrv.pb.hpp>
#include <samples/greeter_service.usrv.pb.hpp>
 
namespace samples {
 
 public:
  static constexpr std::string_view kName = "greeter-client";
 
      : LoggableComponentBase(config, context),
        
        client_factory_(
        
        client_(client_factory_.MakeClient<api::GreeterServiceClient>(
            "greeter", config[
"endpoint"].
As<std::string>())) {}
 
 
  std::string SayHello(std::string name);
 
 
 private:
  api::GreeterServiceClient client_;
};
 
std::string GreeterClient::SayHello(std::string name) {
  api::GreetingRequest request;
  request.set_name(std::move(name));
 
  
  auto context = std::make_unique<grpc::ClientContext>();
  context->set_deadline(
 
  
  
  auto stream = client_.SayHello(request, std::move(context));
 
  
  
  
  
  api::GreetingResponse response = stream.Finish();
 
  return std::move(*response.mutable_greeting());
}
 
  return yaml_config::MergeSchemas<components::LoggableComponentBase>(R"(
type: object
description: >
    a user-defined wrapper around api::GreeterServiceClient that provides
    a simplified interface.
additionalProperties: false
properties:
    endpoint:
        type: string
        description: >
            the service endpoint (URI). We talk to our own service,
            which is kind of pointless, but works for an example
)");
}
 
class GreeterServiceComponent final
    : public api::GreeterServiceBase::Component {
 public:
  static constexpr std::string_view kName = "greeter-service";
 
      : api::GreeterServiceBase::Component(config, context),
        prefix_(config["greeting-prefix"].As<std::string>()) {}
 
  void SayHello(SayHelloCall& call, api::GreetingRequest&& request) override;
 
 
 private:
  const std::string prefix_;
};
 
void GreeterServiceComponent::SayHello(
    api::GreeterServiceBase::SayHelloCall& call,
    api::GreetingRequest&& request) {
  
  
 
  api::GreetingResponse response;
  response.set_greeting(fmt::format("{}, {}!", prefix_, request.name()));
 
  
  
  
  call.Finish(response);
}
 
  return yaml_config::MergeSchemas<ugrpc::server::ServiceComponentBase>(R"(
type: object
description: gRPC sample greater service component
additionalProperties: false
properties:
    greeting-prefix:
        type: string
        description: greeting prefix
)");
}
 
 public:
  static constexpr std::string_view kName = "greeter-http-handler";
 
      : HttpHandlerBase(config, context),
 
  std::string HandleRequestThrow(
    return grpc_greeter_client_.SayHello(request.
RequestBody());
 
  }
 
 private:
  GreeterClient& grpc_greeter_client_;
};
 
}  
 
int main(int argc, char* argv[]) {
  const auto component_list =
          .Append<ugrpc::client::ClientFactoryComponent>()
          .Append<samples::GreeterClient>()
          .Append<samples::GreeterServiceComponent>()
          .Append<samples::GreeterHttpHandler>();
}