// Copyright 2019 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 <fuchsia/examples/llcpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/service/llcpp/service.h>
#include <lib/sys/cpp/component_context.h>

#include <iostream>

using ::llcpp::fuchsia::examples::Echo;
using ::llcpp::fuchsia::examples::EchoService;

fidl::InterfaceHandle<fuchsia::io::Directory> StartEchoServer(
    sys::ComponentContext* context,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
  fidl::InterfaceHandle<fuchsia::io::Directory> svc;
  fuchsia::sys::LaunchInfo info{
      .url = "fuchsia-pkg://fuchsia.com/echo-hlcpp-service-server#meta/echo-server.cmx",
      .directory_request = svc.NewRequest().TakeChannel(),
  };

  auto launcher = context->svc()->Connect<fuchsia::sys::Launcher>();
  launcher->CreateComponent(std::move(info), std::move(controller));
  return svc;
}

zx::status<> llcpp_example(fidl::UnownedClientEnd<llcpp::fuchsia::io::Directory> svc) {
  zx::status<EchoService::ServiceClient> open_result =
      llcpp::sys::OpenServiceAt<EchoService>(std::move(svc));
  if (open_result.is_error()) {
    std::cerr << "failed to open default instance of EchoService: " << open_result.status_string()
              << std::endl;
    return open_result.take_error();
  }

  EchoService::ServiceClient service = std::move(open_result.value());

  zx::status<fidl::ClientEnd<Echo>> connect_result = service.connect_regular_echo();
  if (connect_result.is_error()) {
    std::cerr << "failed to connect to member protocol regular_echo of EchoService: "
              << connect_result.status_string() << std::endl;
    return connect_result.take_error();
  }

  Echo::SyncClient client = fidl::BindSyncClient(std::move(connect_result.value()));
  Echo::ResultOf::EchoString echo_result = client.EchoString(fidl::StringView("hello"));
  if (!echo_result.ok()) {
    std::cerr << "failed to make EchoString call to member protocol regular_echo of EchoService: "
              << echo_result.error() << std::endl;
    return zx::error(ZX_ERR_IO);
  }

  auto response = echo_result.Unwrap();

  std::string result_string(response->response.data(), response->response.size());
  if (result_string != "hello") {
    std::cerr << "got unexpected response '" << result_string << "'. expected 'hello'."
              << std::endl;
    return zx::error(ZX_ERR_INTERNAL);
  }
  return zx::ok();
}

int main(int argc, const char** argv) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();

  // Start the echo service.
  //
  // In a real system, the service would be offered to the client instead of
  // being started by the client.
  fuchsia::sys::ComponentControllerPtr controller;
  auto svc = StartEchoServer(context.get(), controller.NewRequest());

  // Convert the typed handle to LLCPP types.
  auto llsvc = fidl::ClientEnd<llcpp::fuchsia::io::Directory>(svc.TakeChannel());

  zx::status<> result = llcpp_example(llsvc);
  if (result.is_error()) {
    std::cerr << "llcpp_example failed with status: " << result.status_string() << std::endl;
    return 1;
  }
  return 0;
}
