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

#ifndef EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_
#define EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_

#include <fidl/fuchsia.component.runner/cpp/fidl.h>
#include <fidl/fuchsia.io/cpp/fidl.h>
#include <fidl/fuchsia.logger/cpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/async/dispatcher.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/fit/function.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/result.h>

#include <memory>
#include <optional>
#include <string>
#include <unordered_map>

#include "examples/components/pw_rpc/runner/connection.h"
#include "examples/components/pw_rpc/runner/remote_endpoint.h"
#include "pw_stream/socket_stream.h"

class ComponentInstance : public fidl::Server<fuchsia_component_runner::ComponentController> {
 public:
  // Creates an object that manages a component instance's runtime.
  //
  // The object has ownership of the `ComponentController`, and implements the `ComponentController`
  // server.
  //
  // `stream` should contain a socket to the remote Pigweed server endpoint. The socket should have
  // the `O_NONBLOCK` flag.
  ComponentInstance(
      async_dispatcher_t* dispatcher, pw::stream::SocketStream stream,
      fidl::ServerEnd<fuchsia_component_runner::ComponentController> controller_server_end,
      fit::callback<void()> deletion_cb);
  ~ComponentInstance() override;
  ComponentInstance(ComponentInstance&&) = delete;
  ComponentInstance& operator=(ComponentInstance&&) = delete;

  zx::result<> Serve(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir_server_end);

  void Stop(StopCompleter::Sync& completer) override;
  void Kill(KillCompleter::Sync& completer) override;
  void handle_unknown_method(
      fidl::UnknownMethodMetadata<fuchsia_component_runner::ComponentController> metadata,
      fidl::UnknownMethodCompleter::Sync& completer) override {}

  void Start(fidl::ClientEnd<fuchsia_logger::LogSink> log_sink);

  void Close();

 private:
  zx::result<pw::stream::SocketStream> OpenLoggerStream();

  async_dispatcher_t* const dispatcher_;
  fidl::ServerBinding<fuchsia_component_runner::ComponentController> binding_;
  std::shared_ptr<ConnectionGroup> connections_;
  component::OutgoingDirectory outgoing_dir_;
  fit::callback<void()> deletion_cb_;
  zx::eventpair disconnect_event_;
  std::optional<async::WaitOnce> disconnect_wait_;
};

class ComponentRunnerImpl : public fidl::Server<fuchsia_component_runner::ComponentRunner> {
 public:
  explicit ComponentRunnerImpl(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}
  void Start(StartRequest& request, StartCompleter::Sync& completer) override;
  void handle_unknown_method(
      fidl::UnknownMethodMetadata<fuchsia_component_runner::ComponentRunner> metadata,
      fidl::UnknownMethodCompleter::Sync& completer) override {}

 private:
  zx::result<> DoStart(fuchsia_component_runner::ComponentStartInfo start_info,
                       fidl::ServerEnd<fuchsia_component_runner::ComponentController>& controller);

  async_dispatcher_t* const dispatcher_;
  std::unordered_map<uint64_t, std::unique_ptr<ComponentInstance>> components_;
  uint64_t next_component_id_ = 0;
};

#endif  // EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_
