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

#include "test/placeholders/cpp/fidl.h"
#include "lib/async-loop/cpp/loop.h"
#include "lib/async-loop/default.h"
#include "lib/fidl/cpp/binding_set.h"
#include "lib/sys/cpp/component_context.h"
#include "src/lib/fxl/command_line.h"

static constexpr char kCmdHelp[] = "help";
static constexpr char kCmdEcho[] = "echo";
static constexpr char kCmdKill[] = "kill";
static constexpr char kCmdCout[] = "cout";
static constexpr char kCmdCerr[] = "cerr";

static constexpr char kUsage[] = R"(
  Usage: helper_proc [-e] [-k kill_string]

Arguments:
  --help: Shows this help page and exits
  --echo: Exposes an echo service (fidl.examples.echo.Echo)
  --kill=kill_string: will kill the process after echoing a string that equals to kill_string
  --cout=what: Prints argument to standard output
  --cerr=what: Prints argument to standard err
)";

// This helper process can be used in lib component's unittest. You can control
// what it'll do by passing different command-line arguments

class EchoServer : public test::placeholders::Echo {
 public:
  void EchoString(::fidl::StringPtr value, EchoStringCallback callback) override {
    std::string intercept = value.value_or("");
    callback(std::move(value));
    if (listener_) {
      listener_(std::move(intercept));
    }
  }

  fidl::InterfaceRequestHandler<test::placeholders::Echo> GetHandler() {
    return bindings_.GetHandler(this);
  }

  void SetListener(fit::function<void(std::string)> list) { listener_ = std::move(list); }

 private:
  fidl::BindingSet<test::placeholders::Echo> bindings_;
  fit::function<void(std::string)> listener_;
};

int main(int argc, const char** argv) {
  std::cout << "Hello from helper proc." << std::endl;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto cmdline = fxl::CommandLineFromArgcArgv(argc, argv);
  if (cmdline.HasOption(kCmdHelp)) {
    std::cout << kUsage;
    return 0;
  }
  auto startup = sys::ComponentContext::CreateAndServeOutgoingDirectory();
  std::unique_ptr<EchoServer> echo_server;

  if (cmdline.HasOption(kCmdCout)) {
    std::string cout;
    cmdline.GetOptionValue(kCmdCout, &cout);
    std::cout << cout << std::endl;
  }

  if (cmdline.HasOption(kCmdCerr)) {
    std::string cerr;
    cmdline.GetOptionValue(kCmdCerr, &cerr);
    std::cerr << cerr << std::endl;
  }

  if (cmdline.HasOption(kCmdEcho)) {
    echo_server = std::make_unique<EchoServer>();
    startup->outgoing()->AddPublicService(echo_server->GetHandler());
  }

  if (echo_server && cmdline.HasOption(kCmdKill)) {
    std::string kill_str;
    cmdline.GetOptionValue(kCmdKill, &kill_str);
    echo_server->SetListener([&loop, kill_str = std::move(kill_str)](std::string str) {
      if (str == kill_str) {
        loop.Quit();
      }
    });
  }

  if (echo_server) {
    loop.Run();
  }

  std::cout << "Goodbye from helper proc" << std::endl;
  return 0;
}
