// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fidl/test.exampletester/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/syslog/cpp/macros.h>

// An implementation of the Simple protocol.
class SimpleImpl final : public fidl::WireServer<test_exampletester::Simple> {
 public:
  // Bind this implementation to a channel, and store the corresponding client implementation to
  // forward to.
  SimpleImpl(async_dispatcher_t* dispatcher, fidl::ServerEnd<test_exampletester::Simple> server_end,
             fidl::WireClient<test_exampletester::Simple> client_)
      : client_(std::move(client_)),
        binding_(fidl::BindServer(
            dispatcher, std::move(server_end), this,
            [this](SimpleImpl* impl, fidl::UnbindInfo info,
                   fidl::ServerEnd<test_exampletester::Simple> server_end) { delete this; })) {}

  void Add(AddRequestView request, AddCompleter::Sync& completer) override {
    // Forward the request to the server.
    FX_LOGS(INFO) << "Request received";
    client_->Add(request->augend, request->addend)
        .ThenExactlyOnce(
            [completer = completer.ToAsync()](
                fidl::WireUnownedResult<test_exampletester::Simple::Add>& result) mutable {
              // When the request result has bee received, use it to call the async completer and
              // resolve the reply.
              completer.Reply(result->sum);
              FX_LOGS(INFO) << "Response sent";
            });
  }

 private:
  fidl::WireClient<test_exampletester::Simple> client_;
  fidl::ServerBindingRef<test_exampletester::Simple> binding_;
};

int main(int argc, char** argv) {
  FX_LOGS(INFO) << "Started";
  FX_LOGS(INFO) << "trim me (C++ wire)";

  // The event loop is used to asynchronously listen for incoming connections and requests from the
  // client. The following initializes the loop, and obtains the dispatcher, which will be used when
  // binding the server implementation to a channel.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();

  // Create an |OutgoingDirectory| instance.
  //
  // The |component::OutgoingDirectory| class serves the outgoing directory for our component. This
  // directory is where the outgoing FIDL protocols are installed so that they can be provided to
  // other components.
  component::OutgoingDirectory outgoing = component::OutgoingDirectory(dispatcher);

  // The `ServeFromStartupInfo()` function sets up the outgoing directory with the startup handle.
  // The startup handle is a handle provided to every component by the system, so that they can
  // serve capabilities (e.g. FIDL protocols) to other components.
  zx::result result = outgoing.ServeFromStartupInfo();
  if (result.is_error()) {
    FX_LOGS(ERROR) << "Failed to serve outgoing directory: " << result.status_string();
    return -1;
  }

  // Connect to the protocol inside the component's namespace. This can fail so it's wrapped in a
  // |zx::result| and it must be checked for errors.
  zx::result client_end = component::Connect<test_exampletester::Simple>();
  if (!client_end.is_ok()) {
    FX_LOGS(ERROR) << "Synchronous error when connecting to the |Simple| protocol: "
                   << client_end.status_string();
    return -1;
  }
  FX_LOGS(INFO) << "Outgoing connection enabled";

  // Create an asynchronous client using the newly-established connection.
  fidl::WireClient client(std::move(*client_end), dispatcher);

  // Register a handler for components trying to connect to fuchsia.examples.Simple. Each such
  // connection is naively proxied to the server component.
  result = outgoing.AddUnmanagedProtocol<test_exampletester::Simple>(
      [dispatcher, &client](fidl::ServerEnd<test_exampletester::Simple> server_end) {
        new SimpleImpl(dispatcher, std::move(server_end), std::move(client));
      });
  if (result.is_error()) {
    FX_LOGS(ERROR) << "Failed to add Simple protocol: " << result.status_string();
    return -1;
  }

  // Everything is wired up. Sit back and run the loop until an incoming connection wakes us up.
  FX_LOGS(INFO) << "Listening for incoming connections";
  loop.Run();
  return 0;
}
