// 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/fidl.serversuite/cpp/wire_messaging.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>

#include <iostream>

class TargetServer : public fidl::WireServer<fidl_serversuite::Target> {
 public:
  explicit TargetServer(fidl::ClientEnd<fidl_serversuite::Reporter> reporter)
      : reporter_(std::move(reporter)) {}

  void OneWayNoPayload(OneWayNoPayloadRequestView request,
                       OneWayNoPayloadCompleter::Sync& completer) override {
    std::cout << "Target.OneWayNoPayload()" << std::endl;
    auto result = reporter_->ReceivedOneWayNoPayload();
    ZX_ASSERT(result.ok());
  }

 private:
  fidl::WireSyncClient<fidl_serversuite::Reporter> reporter_;
};

class RunnerServer : public fidl::WireServer<fidl_serversuite::Runner> {
 public:
  explicit RunnerServer(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}

  void Start(StartRequestView request, StartCompleter::Sync& completer) override {
    std::cout << "Runner.Start()" << std::endl;

    target_server_ = std::make_unique<TargetServer>(std::move(request->reporter));

    auto endpoints = fidl::CreateEndpoints<fidl_serversuite::Target>();
    fidl::BindServer(dispatcher_, std::move(endpoints->server), target_server_.get(),
                     [](auto*, fidl::UnbindInfo info, auto) {
                       if (!info.is_dispatcher_shutdown() && !info.is_user_initiated() &&
                           !info.is_peer_closed()) {
                         std::cout << "Target unbound with error: " << info.FormatDescription()
                                   << std::endl;
                       }
                     });

    completer.Reply(std::move(endpoints->client));
  }

  void CheckAlive(CheckAliveRequestView request, CheckAliveCompleter::Sync& completer) override {
    completer.Reply();
  }

 private:
  async_dispatcher_t* dispatcher_;
  std::unique_ptr<TargetServer> target_server_;
};

int main(int argc, const char** argv) {
  std::cout << "LLCPP server: main" << std::endl;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  auto outgoing = component::OutgoingDirectory::Create(loop.dispatcher());
  ZX_ASSERT(outgoing.ServeFromStartupInfo().is_ok());
  RunnerServer runner_server(loop.dispatcher());
  auto result = outgoing.AddProtocol<fidl_serversuite::Runner>(&runner_server);
  ZX_ASSERT(result.is_ok());

  std::cout << "LLCPP server: ready!" << std::endl;
  return loop.Run();
}
