// Copyright 2021 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 <type_traits>

#include "pw_bytes/span.h"
#include "pw_rpc/client.h"
#include "pw_rpc/internal/method_info.h"
#include "pw_rpc/internal/packet.h"
#include "pw_rpc/method_type.h"
#include "pw_rpc/raw/fake_channel_output.h"

namespace pw::rpc {

// TODO(pwbug/477): Document the client testing APIs.

// Sends packets to an RPC client as if it were a pw_rpc server.
class FakeServer {
 public:
  constexpr FakeServer(internal::test::FakeChannelOutput& output,
                       Client& client,
                       uint32_t channel_id,
                       ByteSpan packet_buffer)
      : output_(output),
        client_(client),
        channel_id_(channel_id),
        packet_buffer_(packet_buffer) {}

  // Sends a response packet for a server or bidirectional streaming RPC to the
  // client.
  template <auto kMethod,
            typename = std::enable_if_t<
                HasServerStream(internal::MethodInfo<kMethod>::kType)>>
  void SendResponse(Status status) const {
    SendPacket<kMethod>(internal::PacketType::RESPONSE, {}, status);
  }

  // Sends a response packet for a unary or client streaming streaming RPC to
  // the client.
  template <auto kMethod,
            typename = std::enable_if_t<
                !HasServerStream(internal::MethodInfo<kMethod>::kType)>>
  void SendResponse(ConstByteSpan payload, Status status) const {
    SendPacket<kMethod>(internal::PacketType::RESPONSE, payload, status);
  }

  // Sends a stream packet for a server or bidirectional streaming RPC to the
  // client.
  template <auto kMethod>
  void SendServerStream(ConstByteSpan payload) const {
    static_assert(HasServerStream(internal::MethodInfo<kMethod>::kType),
                  "Only server and bidirectional streaming methods can receive "
                  "server stream packets");
    SendPacket<kMethod>(internal::PacketType::SERVER_STREAM, payload);
  }

  // Sends a server error packet to the client.
  template <auto kMethod>
  void SendServerError(Status error) const {
    SendPacket<kMethod>(internal::PacketType::SERVER_ERROR, {}, error);
  }

 private:
  template <auto kMethod>
  void SendPacket(internal::PacketType type,
                  ConstByteSpan payload = {},
                  Status status = OkStatus()) const {
    using Info = internal::MethodInfo<kMethod>;
    CheckProcessPacket(
        type, Info::kServiceId, Info::kMethodId, payload, status);
  }

  void CheckProcessPacket(internal::PacketType type,
                          uint32_t service_id,
                          uint32_t method_id,
                          ConstByteSpan payload,
                          Status status) const;

  Status ProcessPacket(internal::PacketType type,
                       uint32_t service_id,
                       uint32_t method_id,
                       ConstByteSpan payload,
                       Status status) const;

  internal::test::FakeChannelOutput& output_;
  Client& client_;
  const uint32_t channel_id_;
  ByteSpan packet_buffer_;
};

// Instantiates a FakeServer, Client, Channel, and RawFakeChannelOutput for
// testing RPC client calls. These components may be used individually, but are
// instantiated together for convenience.
template <size_t kMaxPackets = 10,
          size_t kPacketEncodeBufferSizeBytes = 128,
          size_t kPayloadsBufferSizeBytes = 256>
class RawClientTestContext {
 public:
  static constexpr uint32_t kDefaultChannelId = 1;

  constexpr RawClientTestContext()
      : channel_(Channel::Create<kDefaultChannelId>(&channel_output_)),
        client_(std::span(&channel_, 1)),
        packet_buffer_{},
        fake_server_(
            channel_output_, client_, kDefaultChannelId, packet_buffer_) {}

  const Channel& channel() const { return channel_; }
  Channel& channel() { return channel_; }

  const FakeServer& server() const { return fake_server_; }
  FakeServer& server() { return fake_server_; }

  const Client& client() const { return client_; }
  Client& client() { return client_; }

  const auto& output() const { return channel_output_; }

 private:
  RawFakeChannelOutput<kMaxPackets,
                       kPacketEncodeBufferSizeBytes,
                       kPayloadsBufferSizeBytes>
      channel_output_;
  Channel channel_;
  Client client_;
  std::byte packet_buffer_[kPacketEncodeBufferSizeBytes];
  FakeServer fake_server_;
};

}  // namespace pw::rpc
