// 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 <cstddef>
#include <cstdint>
#include <span>

#include "pw_bytes/span.h"
#include "pw_protobuf/serialized_size.h"
#include "pw_rpc/internal/packet.pwpb.h"
#include "pw_status/status_with_size.h"

namespace pw::rpc::internal {

class Packet {
 public:
  static constexpr uint32_t kUnassignedId = 0;

  static constexpr size_t kMinEncodedSizeWithoutPayload =
      protobuf::SizeOfFieldEnum(RpcPacket::Fields::TYPE, 7) +
      protobuf::SizeOfFieldUint32(RpcPacket::Fields::CHANNEL_ID) +
      protobuf::SizeOfFieldUint32(RpcPacket::Fields::SERVICE_ID) +
      protobuf::SizeOfFieldUint32(RpcPacket::Fields::METHOD_ID) +
      protobuf::SizeOfDelimitedFieldWithoutValue(RpcPacket::Fields::PAYLOAD) +
      protobuf::SizeOfFieldUint32(RpcPacket::Fields::STATUS,
                                  Status::Unauthenticated().code()) +
      protobuf::SizeOfFieldUint32(RpcPacket::Fields::CALL_ID);
  ;

  // Parses a packet from a protobuf message. Missing or malformed fields take
  // their default values.
  static Result<Packet> FromBuffer(ConstByteSpan data);

  // Creates an RPC packet with the channel, service, and method ID of the
  // provided packet.
  static constexpr Packet Response(const Packet& request,
                                   Status status = OkStatus()) {
    return Packet(PacketType::RESPONSE,
                  request.channel_id(),
                  request.service_id(),
                  request.method_id(),
                  request.call_id(),
                  {},
                  status);
  }

  // Creates a SERVER_ERROR packet with the channel, service, and method ID of
  // the provided packet.
  static constexpr Packet ServerError(const Packet& packet, Status status) {
    return Packet(PacketType::SERVER_ERROR,
                  packet.channel_id(),
                  packet.service_id(),
                  packet.method_id(),
                  packet.call_id(),
                  {},
                  status);
  }

  // Creates a CLIENT_ERROR packet with the channel, service, and method ID of
  // the provided packet.
  static constexpr Packet ClientError(const Packet& packet, Status status) {
    return Packet(PacketType::CLIENT_ERROR,
                  packet.channel_id(),
                  packet.service_id(),
                  packet.method_id(),
                  packet.call_id(),
                  {},
                  status);
  }

  // Creates an empty packet.
  constexpr Packet()
      : Packet(PacketType{}, kUnassignedId, kUnassignedId, kUnassignedId) {}

  constexpr Packet(PacketType type,
                   uint32_t channel_id,
                   uint32_t service_id,
                   uint32_t method_id,
                   uint32_t call_id = kUnassignedId,
                   ConstByteSpan payload = {},
                   Status status = OkStatus())
      : type_(type),
        channel_id_(channel_id),
        service_id_(service_id),
        method_id_(method_id),
        call_id_(call_id),
        payload_(payload),
        status_(status) {}

  // Encodes the packet into its wire format. Returns the encoded size.
  Result<ConstByteSpan> Encode(ByteSpan buffer) const;

  // Determines the space required to encode the packet proto fields for a
  // response, excluding the payload. This may be used to split the buffer into
  // reserved space and available space for the payload.
  //
  // This method allocates two bytes for the status. Status code 0 (OK) is not
  // encoded since 0 is the default value.
  size_t MinEncodedSizeBytes() const;

  enum Destination : bool { kServer, kClient };

  constexpr Destination destination() const {
    return static_cast<int>(type_) % 2 == 0 ? kServer : kClient;
  }

  constexpr PacketType type() const { return type_; }
  constexpr uint32_t channel_id() const { return channel_id_; }
  constexpr uint32_t service_id() const { return service_id_; }
  constexpr uint32_t method_id() const { return method_id_; }
  constexpr uint32_t call_id() const { return call_id_; }
  constexpr const ConstByteSpan& payload() const { return payload_; }
  constexpr const Status& status() const { return status_; }

  constexpr void set_type(PacketType type) { type_ = type; }
  constexpr void set_channel_id(uint32_t channel_id) {
    channel_id_ = channel_id;
  }
  constexpr void set_service_id(uint32_t service_id) {
    service_id_ = service_id;
  }
  constexpr void set_method_id(uint32_t method_id) { method_id_ = method_id; }
  constexpr void set_call_id(uint32_t call_id) { call_id_ = call_id; }
  constexpr void set_payload(ConstByteSpan payload) { payload_ = payload; }
  constexpr void set_status(Status status) { status_ = status; }

 private:
  PacketType type_;
  uint32_t channel_id_;
  uint32_t service_id_;
  uint32_t method_id_;
  uint32_t call_id_;
  ConstByteSpan payload_;
  Status status_;
};

}  // namespace pw::rpc::internal
