// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once

#include "pb_common.h"
#include "pw_bytes/span.h"
#include "pw_rpc/internal/lock.h"
#include "pw_status/status_with_size.h"

namespace pw::rpc::internal {

// Nanopb 0.3 uses pb_field_t, but Nanopb 4 uses pb_msgdesc_t. Determine which
// type to use by deducing it from the pb_field_iter_begin function.
template <typename PbFieldIterBeginFunction>
struct NanopbDescriptorTraits;

template <typename T>
struct NanopbDescriptorTraits<bool(pb_field_iter_t*, T, void*)> {
  using Type = T;
};

using NanopbMessageDescriptor =
    NanopbDescriptorTraits<decltype(pb_field_iter_begin)>::Type;

// Serializer/deserializer for a Nanopb protobuf message.
class NanopbSerde {
 public:
  explicit constexpr NanopbSerde(NanopbMessageDescriptor fields)
      : fields_(fields) {}

  NanopbSerde(const NanopbSerde&) = default;
  NanopbSerde& operator=(const NanopbSerde&) = default;

  // Encodes a Nanopb protobuf struct to the serialized wire format.
  StatusWithSize Encode(const void* proto_struct, ByteSpan buffer) const;

  // Decodes a serialized protobuf to a Nanopb struct.
  bool Decode(ConstByteSpan buffer, void* proto_struct) const;

 private:
  NanopbMessageDescriptor fields_;
};

// Serializer/deserializer for Nanopb message request and response structs in an
// RPC method.
class NanopbMethodSerde {
 public:
  constexpr NanopbMethodSerde(NanopbMessageDescriptor request_fields,
                              NanopbMessageDescriptor response_fields)
      : request_fields_(request_fields), response_fields_(response_fields) {}

  NanopbMethodSerde(const NanopbMethodSerde&) = delete;
  NanopbMethodSerde& operator=(const NanopbMethodSerde&) = delete;

  StatusWithSize EncodeRequest(const void* proto_struct,
                               ByteSpan buffer) const {
    return request_fields_.Encode(proto_struct, buffer);
  }
  StatusWithSize EncodeResponse(const void* proto_struct,
                                ByteSpan buffer) const {
    return response_fields_.Encode(proto_struct, buffer);
  }

  bool DecodeRequest(ConstByteSpan buffer, void* proto_struct) const {
    return request_fields_.Decode(buffer, proto_struct);
  }
  bool DecodeResponse(ConstByteSpan buffer, void* proto_struct) const {
    return response_fields_.Decode(buffer, proto_struct);
  }

  const NanopbSerde& request() const { return request_fields_; }
  const NanopbSerde& response() const { return response_fields_; }

 private:
  NanopbSerde request_fields_;
  NanopbSerde response_fields_;
};

template <NanopbMessageDescriptor kRequest, NanopbMessageDescriptor kResponse>
inline constexpr NanopbMethodSerde kNanopbMethodSerde(kRequest, kResponse);

class Call;
class ClientCall;
class NanopbServerCall;

// [Client] Encodes and sends the initial request message for the call.
// active() must be true.
void NanopbSendInitialRequest(ClientCall& call,
                              NanopbSerde serde,
                              const void* payload)
    PW_UNLOCK_FUNCTION(rpc_lock());

// [Client/Server] Encodes and sends a client or server stream message.
// active() must be true.
Status NanopbSendStream(Call& call, const void* payload, NanopbSerde serde)
    PW_LOCKS_EXCLUDED(rpc_lock());

// [Server] Encodes and sends the final response message.
// Returns Status::FailedPrecondition if active() is false.
Status SendFinalResponse(NanopbServerCall& call,
                         const void* payload,
                         Status status) PW_LOCKS_EXCLUDED(rpc_lock());

}  // namespace pw::rpc::internal
