// 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.

// [START imports]
#include <fidl/examples.routing.echo/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/inspect/component/cpp/component.h>
#include <lib/syslog/cpp/macros.h>
// [END imports]

// [START handler]
// Handler for incoming FIDL protocol requests
class EchoImplementation : public fidl::Server<examples_routing_echo::Echo> {
public:
  // The handler for `examples.routing.echo/Echo.EchoString` requests.
  //
  // Replies back to the caller with the original request value.
  void EchoString(EchoStringRequest &request,
                  EchoStringCompleter::Sync &completer) override {
    completer.Reply({{request.value()}});
  }

  // Called when the FIDL connection is torn down.
  void OnUnbound(fidl::UnbindInfo info,
                 fidl::ServerEnd<examples_routing_echo::Echo> server_end) {
    if (info.is_user_initiated()) {
      return;
    }
    if (info.is_peer_closed()) {
      // The peer (the client) closed their endpoint.
      FX_LOGST(DEBUG, "echo_server") << "Client disconnected.";
    } else {
      // Treat other unbind causes as errors.
      FX_LOGST(ERROR, "echo_server")
          << "Server error: " << info.status_string();
    }
  }
};
// [END handler]

// [START main_body]
int main(int argc, const char **argv) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  component::OutgoingDirectory outgoing =
      component::OutgoingDirectory(loop.dispatcher());

  // Initialize inspect
  inspect::ComponentInspector inspector(loop.dispatcher(), {});
  inspector.Health().StartingUp();

  // Serve the Echo protocol
  std::unique_ptr<EchoImplementation> echo_instance =
      std::make_unique<EchoImplementation>();
  zx::result result = outgoing.AddProtocol<examples_routing_echo::Echo>(
      std::move(echo_instance));
  if (result.is_error()) {
    FX_LOGST(ERROR, "echo_server")
        << "Failed to add Echo protocol: " << result.status_string();
    return -1;
  }

  result = outgoing.ServeFromStartupInfo();
  if (result.is_error()) {
    FX_LOGST(ERROR, "echo_server")
        << "Failed to serve outgoing directory: " << result.status_string();
    return -1;
  }

  // Component is serving and ready to handle incoming requests
  inspector.Health().Ok();

  return loop.Run();
}
// [END main_body]
