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

#ifndef SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_CLIENT_CLIENT_IMPL_H_
#define SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_CLIENT_CLIENT_IMPL_H_

#include <lib/fdio/fd.h>
#include <zircon/system/ulib/fit/include/lib/fit/function.h>

#include <filesystem>

#include "src/virtualization/lib/grpc/fdio_util.h"
#include "src/virtualization/lib/guest_interaction/client/client_operation_state.h"
#include "src/virtualization/lib/guest_interaction/platform_interface/platform_interface.h"
#include "src/virtualization/lib/guest_interaction/proto/guest_interaction.grpc.pb.h"

template <class T>
class ClientImpl {
 public:
  explicit ClientImpl(uint32_t vsock_fd);
  void Get(const std::string& source, zx::channel channel, TransferCallback callback);
  void Put(zx::channel source_channel, const std::string& destination, TransferCallback callback);
  void Exec(const std::string& command, const std::map<std::string, std::string>& env_vars,
            zx::socket std_in, zx::socket std_out, zx::socket std_err,
            fidl::InterfaceRequest<fuchsia::netemul::guest::CommandListener> listener);
  void Run();
  void Stop();

 private:
  grpc::CompletionQueue cq_;
  std::unique_ptr<GuestInteractionService::Stub> stub_;

  bool should_run_;
  T platform_interface_;
};

// The gRPC channel internals take responsibility for closing the supplied vsock_fd.
template <class T>
ClientImpl<T>::ClientImpl(uint32_t vsock_fd) : should_run_(true) {
  stub_ = GuestInteractionService::NewStub(grpc::CreateInsecureChannelFromFd("vsock", vsock_fd));
}

template <class T>
void ClientImpl<T>::Run() {
  void* tag;
  bool ok;
  gpr_timespec wait_time = {};

  should_run_ = true;

  while (should_run_) {
    grpc::CompletionQueue::NextStatus status = cq_.AsyncNext(&tag, &ok, wait_time);
    if (status == grpc::CompletionQueue::GOT_EVENT) {
      static_cast<CallData*>(tag)->Proceed(ok);
    }
  }
}

template <class T>
void ClientImpl<T>::Stop() {
  should_run_ = false;
}

template <class T>
void ClientImpl<T>::Get(const std::string& source, zx::channel channel, TransferCallback callback) {
  int32_t fd;
  zx_status_t fd_create_status = fdio_fd_create(channel.release(), &fd);
  if (fd_create_status != ZX_OK) {
    callback(OperationStatus::CLIENT_CREATE_FILE_FAILURE);
    return;
  }

  GetRequest get_request;
  get_request.set_source(source);

  GetCallData<T>* call_data = new GetCallData<T>(fd, std::move(callback));
  call_data->reader_ = stub_->PrepareAsyncGet(&(call_data->ctx_), get_request, &cq_);
  call_data->reader_->StartCall(call_data);
}

template <class T>
void ClientImpl<T>::Put(zx::channel source_channel, const std::string& destination,
                        TransferCallback callback) {
  int32_t fd;
  zx_status_t fd_create_status = fdio_fd_create(source_channel.release(), &fd);
  if (fd_create_status != ZX_OK) {
    callback(OperationStatus::CLIENT_FILE_READ_FAILURE);
    return;
  }

  PutCallData<T>* call_data = new PutCallData<T>(fd, destination, std::move(callback));
  call_data->writer_ = stub_->PrepareAsyncPut(&(call_data->ctx_), &(call_data->response_), &cq_);
  call_data->writer_->StartCall(call_data);
}

template <class T>
void ClientImpl<T>::Exec(const std::string& command,
                         const std::map<std::string, std::string>& env_vars, zx::socket std_in,
                         zx::socket std_out, zx::socket std_err,
                         fidl::InterfaceRequest<fuchsia::netemul::guest::CommandListener> req) {
  // Convert the provided zx::sockets into FD's.
  int32_t stdin_fd = ConvertSocketToNonBlockingFd(std::move(std_in));
  int32_t stdout_fd = ConvertSocketToNonBlockingFd(std::move(std_out));
  int32_t stderr_fd = ConvertSocketToNonBlockingFd(std::move(std_err));

  std::unique_ptr<ListenerInterface> listener = std::make_unique<ListenerInterface>(std::move(req));

  ExecCallData<T>* call_data =
      new ExecCallData<T>(command, env_vars, stdin_fd, stdout_fd, stderr_fd, std::move(listener));
  call_data->rw_ = stub_->PrepareAsyncExec(call_data->ctx_.get(), &cq_);
  call_data->rw_->StartCall(call_data);
}

#endif  // SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_CLIENT_CLIENT_IMPL_H_
