// Copyright 2022 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 <lib/fidl/llcpp/wire_coding_traits.h>

namespace fidl::internal {

void WireDecodeUnknownEnvelope(WireDecoder* decoder, WirePosition position) {
  const fidl_envelope_v2_t* envelope = position.As<fidl_envelope_v2_t>();
  if (envelope->flags == 0) {
    if (envelope->num_bytes % FIDL_ALIGNMENT != 0) {
      decoder->SetError(kCodingErrorInvalidNumBytesSpecifiedInEnvelope);
      return;
    }
    WirePosition new_position;
    if (!decoder->Alloc(envelope->num_bytes, &new_position)) {
      return;
    }
  } else if (envelope->flags != FIDL_ENVELOPE_FLAGS_INLINING_MASK) {
    decoder->SetError(kCodingErrorInvalidInlineBit);
    return;
  }
  decoder->CloseNextNHandles(envelope->num_handles);
}

fitx::result<fidl::Error, WireEncoder::Result> WireEncode(
    size_t inline_size, TopLevelEncodeFn encode_fn, const CodingConfig* coding_config, void* value,
    zx_channel_iovec_t* iovecs, size_t iovec_capacity, fidl_handle_t* handles,
    fidl_handle_metadata_t* handle_metadata, size_t handle_capacity, uint8_t* backing_buffer,
    size_t backing_buffer_capacity) {
  if (unlikely(value == nullptr)) {
    return fitx::error(fidl::Error::DecodeError(ZX_ERR_INVALID_ARGS, kCodingErrorNullIovecBuffer));
  }
  if (unlikely(iovecs == nullptr)) {
    return fitx::error(fidl::Error::DecodeError(ZX_ERR_INVALID_ARGS, kCodingErrorNullIovecBuffer));
  }
  if (unlikely(handle_capacity > 0 && handles == nullptr)) {
    return fitx::error(
        fidl::Error::DecodeError(ZX_ERR_INVALID_ARGS, kCodingErrorNullHandleBufferButNonzeroCount));
  }
  if (unlikely(backing_buffer == nullptr)) {
    return fitx::error(fidl::Error::DecodeError(ZX_ERR_INVALID_ARGS, kCodingErrorNullByteBuffer));
  }
  WireEncoder encoder(coding_config, iovecs, iovec_capacity, handles, handle_metadata,
                      handle_capacity, backing_buffer, backing_buffer_capacity);
  WirePosition position;
  if (likely(encoder.Alloc(inline_size, &position))) {
    encode_fn(&encoder, value, position);
  }
  return encoder.Finish();
}

fidl::Status WireDecode(size_t inline_size, TopLevelDecodeFn decode_fn,
                        const CodingConfig* coding_config, uint8_t* bytes, size_t num_bytes,
                        fidl_handle_t* handles, fidl_handle_metadata_t* handle_metadata,
                        size_t num_handles) {
  if (unlikely(bytes == nullptr)) {
    return fidl::Status::DecodeError(ZX_ERR_INVALID_ARGS, kCodingErrorNullByteBuffer);
  }
  if (unlikely(num_handles > 0 && handles == nullptr)) {
    return fidl::Status::DecodeError(ZX_ERR_INVALID_ARGS,
                                     kCodingErrorNullHandleBufferButNonzeroCount);
  }
  WireDecoder decoder(coding_config, bytes, num_bytes, handles, handle_metadata, num_handles);
  WirePosition position;
  if (likely(decoder.Alloc(inline_size, &position))) {
    decode_fn(&decoder, position);
  }
  if (unlikely(decoder.CurrentLength() < num_bytes)) {
    decoder.SetError(kCodingErrorNotAllBytesConsumed);
  }
  if (unlikely(decoder.CurrentHandleCount() < num_handles)) {
    decoder.SetError(kCodingErrorNotAllHandlesConsumed);
  }
  return decoder.Finish();
}

}  // namespace fidl::internal
