// 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.

#include "pw_rpc/internal/fake_channel_output.h"

#include <array>
#include <cstddef>
#include <memory>

#include "gtest/gtest.h"
#include "pw_rpc/internal/channel.h"
#include "pw_rpc/internal/packet.h"

namespace pw::rpc::internal::test {
namespace {

constexpr size_t kOutputSize = 50;
constexpr uint32_t kChannelId = 1;
constexpr uint32_t kServiceId = 1;
constexpr uint32_t kMethodId = 1;
constexpr std::array<std::byte, 3> kPayload = {
    std::byte(1), std::byte(2), std::byte(3)};

class TestFakeChannelOutput final
    : public FakeChannelOutputBuffer<kOutputSize, 9, 128> {
 public:
  TestFakeChannelOutput() = default;

  const ConstByteSpan& last_response(MethodType type) {
    return payloads(type, kChannelId, kServiceId, kMethodId).back();
  }
};

TEST(FakeChannelOutput, SendAndClear) {
  TestFakeChannelOutput output;
  Channel channel(kChannelId, &output);
  const internal::Packet server_stream_packet(
      PacketType::SERVER_STREAM, kChannelId, kServiceId, kMethodId, kPayload);
  ASSERT_EQ(channel.Send(server_stream_packet), OkStatus());
  ASSERT_EQ(output.last_response(MethodType::kServerStreaming).size(),
            kPayload.size());
  EXPECT_EQ(
      std::memcmp(output.last_response(MethodType::kServerStreaming).data(),
                  kPayload.data(),
                  kPayload.size()),
      0);
  EXPECT_EQ(output.total_stream_packets(), 1u);
  EXPECT_EQ(output.total_response_packets(), 0u);
  EXPECT_EQ(output.total_responses(), 1u);
  EXPECT_FALSE(output.done());

  output.clear();
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 0u);
  EXPECT_EQ(output.total_responses(), 0u);
  EXPECT_FALSE(output.done());
}

TEST(FakeChannelOutput, SendAndFakeFutureResults) {
  TestFakeChannelOutput output;
  Channel channel(kChannelId, &output);
  const internal::Packet response_packet(
      PacketType::RESPONSE, kChannelId, kServiceId, kMethodId, kPayload);
  EXPECT_EQ(channel.Send(response_packet), OkStatus());
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 1u);
  EXPECT_EQ(output.total_responses(), 1u);
  EXPECT_TRUE(output.done());

  // Multiple calls will return the same error status.
  output.set_send_status(Status::Unknown());
  EXPECT_EQ(channel.Send(response_packet), Status::Unknown());
  EXPECT_EQ(channel.Send(response_packet), Status::Unknown());
  EXPECT_EQ(channel.Send(response_packet), Status::Unknown());
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 1u);
  EXPECT_EQ(output.total_responses(), 1u);

  // Turn off error status behavior.
  output.set_send_status(OkStatus());
  EXPECT_EQ(channel.Send(response_packet), OkStatus());
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 2u);
  EXPECT_EQ(output.total_responses(), 2u);

  const internal::Packet server_stream_packet(
      PacketType::SERVER_STREAM, kChannelId, kServiceId, kMethodId, kPayload);
  EXPECT_EQ(channel.Send(server_stream_packet), OkStatus());
  ASSERT_EQ(output.last_response(MethodType::kUnary).size(), kPayload.size());
  EXPECT_EQ(std::memcmp(output.last_response(MethodType::kUnary).data(),
                        kPayload.data(),
                        kPayload.size()),
            0);
  EXPECT_EQ(output.total_stream_packets(), 1u);
  EXPECT_EQ(output.total_response_packets(), 2u);
  EXPECT_EQ(output.total_responses(), 3u);
  EXPECT_TRUE(output.done());
}

TEST(FakeChannelOutput, SendAndFakeSingleResult) {
  TestFakeChannelOutput output;
  Channel channel(kChannelId, &output);
  const internal::Packet response_packet(
      PacketType::RESPONSE, kChannelId, kServiceId, kMethodId, kPayload);
  // Multiple calls will return the same error status.
  const int packet_count_fail = 4;
  output.set_send_status(Status::Unknown(), packet_count_fail);
  for (int i = 0; i < packet_count_fail; ++i) {
    EXPECT_EQ(channel.Send(response_packet), OkStatus());
  }
  EXPECT_EQ(channel.Send(response_packet), Status::Unknown());
  for (int i = 0; i < packet_count_fail; ++i) {
    EXPECT_EQ(channel.Send(response_packet), OkStatus());
  }

  const size_t total_response_packets =
      static_cast<size_t>(2 * packet_count_fail);
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), total_response_packets);
  EXPECT_EQ(output.total_responses(), total_response_packets);

  // Turn off error status behavior.
  output.set_send_status(OkStatus());
  EXPECT_EQ(channel.Send(response_packet), OkStatus());
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), total_response_packets + 1);
  EXPECT_EQ(output.total_responses(), total_response_packets + 1);
}

TEST(FakeChannelOutput, SendResponseUpdated) {
  TestFakeChannelOutput output;
  Channel channel(kChannelId, &output);
  const internal::Packet response_packet(
      PacketType::RESPONSE, kChannelId, kServiceId, kMethodId, kPayload);
  ASSERT_EQ(channel.Send(response_packet), OkStatus());
  ASSERT_EQ(output.last_response(MethodType::kUnary).size(), kPayload.size());
  EXPECT_EQ(std::memcmp(output.last_response(MethodType::kUnary).data(),
                        kPayload.data(),
                        kPayload.size()),
            0);
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 1u);
  EXPECT_EQ(output.total_responses(), 1u);
  EXPECT_TRUE(output.done());

  output.clear();
  const internal::Packet packet_empty_payload(
      PacketType::RESPONSE, kChannelId, kServiceId, kMethodId, {});
  EXPECT_EQ(channel.Send(packet_empty_payload), OkStatus());
  EXPECT_EQ(output.last_response(MethodType::kUnary).size(), 0u);
  EXPECT_EQ(output.total_stream_packets(), 0u);
  EXPECT_EQ(output.total_response_packets(), 1u);
  EXPECT_EQ(output.total_responses(), 1u);
  EXPECT_TRUE(output.done());

  const internal::Packet server_stream_packet(
      PacketType::SERVER_STREAM, kChannelId, kServiceId, kMethodId, kPayload);
  ASSERT_EQ(channel.Send(server_stream_packet), OkStatus());
  ASSERT_EQ(output.last_response(MethodType::kServerStreaming).size(),
            kPayload.size());
  EXPECT_EQ(
      std::memcmp(output.last_response(MethodType::kServerStreaming).data(),
                  kPayload.data(),
                  kPayload.size()),
      0);
  EXPECT_EQ(output.total_stream_packets(), 1u);
  EXPECT_EQ(output.total_response_packets(), 1u);
  EXPECT_EQ(output.total_responses(), 2u);
  EXPECT_TRUE(output.done());
}

}  // namespace
}  // namespace pw::rpc::internal::test
