// 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 "src/virtualization/lib/grpc/grpc_vsock_server.h"

#include <lib/fit/bridge.h>
#include <lib/syslog/cpp/macros.h>

#include "src/virtualization/lib/grpc/fdio_util.h"

void GrpcVsockServerBuilder::RegisterService(grpc::Service* service) {
  builder_->RegisterService(service);
}

void GrpcVsockServerBuilder::AddListenPort(uint32_t vsock_port) {
  fit::bridge<void, zx_status_t> bridge;
  (*socket_endpoint_)
      ->Listen(vsock_port, server_->NewBinding(),
               // The unused capture of |socket_endpoint_| here is important.
               // This is a shared_ptr we need to keep alive longer than this
               // closure so ensure the FIDL reply will be delivered. If we
               // don't do this, the underlying channel may be closed if the
               // builder is free'd after a call to Build().
               [socket_endpoint = socket_endpoint_,
                completer = std::move(bridge.completer)](zx_status_t status) mutable {
                 if (status != ZX_OK) {
                   completer.complete_error(status);
                 } else {
                   completer.complete_ok();
                 }
               });
  service_promises_.push_back(bridge.consumer.promise());
}

fit::promise<std::unique_ptr<GrpcVsockServer>, zx_status_t> GrpcVsockServerBuilder::Build() {
  return fit::join_promise_vector(std::move(service_promises_))
      .then([builder = std::move(builder_)](
                const fit::result<std::vector<fit::result<void, zx_status_t>>>& result) mutable
            -> fit::result<std::unique_ptr<grpc::Server>, zx_status_t> {
        // join_promise_vector should never fail, but instead return a vector
        // of results.
        FX_CHECK(result.is_ok()) << "fit::join_promise_vector returns fit::error";
        for (const auto& result : result.value()) {
          if (result.is_error()) {
            FX_CHECK(false) << "Failed to listen on vsock port: " << result.error();
            return fit::error(result.error());
          }
        }
        // All the vsock listeners have been initialized. Now start the gRPC
        // server.
        return fit::ok(builder->BuildAndStart());
      })
      .and_then([server = std::move(server_)](std::unique_ptr<grpc::Server>& server_impl) mutable {
        server->SetServerImpl(std::move(server_impl));
        return fit::ok(std::move(server));
      });
}

// This method is registered as a FIDL callback for all of our vsock port
// listeners. In response we need to allocate a new zx::socket to use for the
// connection and register one end with gRPC.
void GrpcVsockServer::Accept(uint32_t src_cid, uint32_t src_port, uint32_t port,
                             AcceptCallback callback) {
  FX_CHECK(server_);
  zx::socket h1, h2;
  zx_status_t status = zx::socket::create(ZX_SOCKET_STREAM, &h1, &h2);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to create socket " << status;
    callback(ZX_ERR_CONNECTION_REFUSED, zx::handle());
    return;
  }

  // gRPC is not compatible with Zircon primitives, so we need to provide it
  // with a compatible file descriptor instead.
  int fd = ConvertSocketToNonBlockingFd(std::move(h1));
  if (fd < 0) {
    FX_LOGS(ERROR) << "Failed get file descriptor for socket";
    callback(ZX_ERR_INTERNAL, zx::socket());
    return;
  }
  grpc::AddInsecureChannelFromFd(server_.get(), fd);
  callback(ZX_OK, std::move(h2));
}
