//===--- GPU helper functions for printf using RPC ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "hdr/types/FILE.h"
#include "src/__support/GPU/utils.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/arg_list.h"
#include "src/stdio/gpu/file.h"
#include "src/string/string_utils.h"

namespace LIBC_NAMESPACE_DECL {

template <uint32_t opcode>
LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
                              const char *__restrict format, size_t format_size,
                              va_list vlist) {
  uint64_t mask = gpu::get_lane_mask();
  rpc::Client::Port port = rpc::client.open<opcode>();

  if constexpr (opcode == LIBC_PRINTF_TO_STREAM ||
                opcode == LIBC_PRINTF_TO_STREAM_PACKED) {
    port.send([&](rpc::Buffer *buffer, uint32_t) {
      buffer->data[0] = reinterpret_cast<uintptr_t>(file);
    });
  }

  size_t args_size = 0;
  port.send_n(format, format_size);
  port.recv([&](rpc::Buffer *buffer, uint32_t) {
    args_size = static_cast<size_t>(buffer->data[0]);
  });
  port.send_n(vlist, args_size);

  uint32_t ret = 0;
  for (;;) {
    const char *str = nullptr;
    port.recv([&](rpc::Buffer *buffer, uint32_t) {
      ret = static_cast<uint32_t>(buffer->data[0]);
      str = reinterpret_cast<const char *>(buffer->data[1]);
    });
    // If any lanes have a string argument it needs to be copied back.
    if (!gpu::ballot(mask, str))
      break;

    uint64_t size = str ? internal::string_length(str) + 1 : 0;
    port.send_n(str, size);
  }

  return ret;
}

LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream,
                                  const char *__restrict format,
                                  size_t format_size, va_list vlist) {
  // The AMDPGU backend uses a packed struct for its varargs. We pass it as a
  // separate opcode so the server knows how much to advance the pointers.
#if defined(LIBC_TARGET_ARCH_IS_AMDGPU)
  if (stream == stdout)
    return vfprintf_impl<LIBC_PRINTF_TO_STDOUT_PACKED>(stream, format,
                                                       format_size, vlist);
  else if (stream == stderr)
    return vfprintf_impl<LIBC_PRINTF_TO_STDERR_PACKED>(stream, format,
                                                       format_size, vlist);
  else
    return vfprintf_impl<LIBC_PRINTF_TO_STREAM_PACKED>(stream, format,
                                                       format_size, vlist);
#else
  if (stream == stdout)
    return vfprintf_impl<LIBC_PRINTF_TO_STDOUT>(stream, format, format_size,
                                                vlist);
  else if (stream == stderr)
    return vfprintf_impl<LIBC_PRINTF_TO_STDERR>(stream, format, format_size,
                                                vlist);
  else
    return vfprintf_impl<LIBC_PRINTF_TO_STREAM>(stream, format, format_size,
                                                vlist);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
