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

#include "pw_rpc/channel.h"

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

namespace pw::rpc::internal {
namespace {

using std::byte;

TEST(ChannelOutput, Name) {
  class NameTester : public ChannelOutput {
   public:
    NameTester(const char* name) : ChannelOutput(name) {}
    std::span<std::byte> AcquireBuffer() override { return {}; }
    Status SendAndReleaseBuffer(std::span<const std::byte>) override {
      return OkStatus();
    }
  };

  EXPECT_STREQ("hello_world", NameTester("hello_world").name());
  EXPECT_EQ(nullptr, NameTester(nullptr).name());
}

constexpr Packet kTestPacket(
    PacketType::RESPONSE, 1, 42, 100, 0, {}, Status::NotFound());
const size_t kReservedSize = 2 /* type */ + 2 /* channel */ + 5 /* service */ +
                             5 /* method */ + 2 /* payload key */ +
                             2 /* status (if not OK) */;

enum class ChannelId {
  kOne = 1,
  kTwo = 2,
};

TEST(Channel, Create_FromEnum) {
  constexpr rpc::Channel one = Channel::Create<ChannelId::kOne>(nullptr);
  constexpr rpc::Channel two = Channel::Create<ChannelId::kTwo>(nullptr);
  static_assert(one.id() == 1);
  static_assert(two.id() == 2);
}

TEST(Channel, TestPacket_ReservedSizeMatchesMinEncodedSizeBytes) {
  EXPECT_EQ(kReservedSize, kTestPacket.MinEncodedSizeBytes());
}

TEST(Channel, OutputBuffer_EmptyBuffer) {
  TestOutput<0> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer buffer = channel.AcquireBuffer();
  EXPECT_TRUE(buffer.payload(kTestPacket).empty());
}

TEST(Channel, OutputBuffer_TooSmall) {
  TestOutput<kReservedSize - 2 /* payload key & size */ - 1> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer output_buffer = channel.AcquireBuffer();
  EXPECT_TRUE(output_buffer.payload(kTestPacket).empty());

  rpc_lock().lock();
  EXPECT_EQ(Status::Internal(), channel.SendBuffer(output_buffer, kTestPacket));
}

TEST(Channel, OutputBuffer_ExactFit) {
  TestOutput<kReservedSize> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer output_buffer(channel.AcquireBuffer());
  const std::span payload = output_buffer.payload(kTestPacket);

  EXPECT_EQ(payload.size(), output.buffer().size() - kReservedSize);
  EXPECT_EQ(output.buffer().data() + kReservedSize, payload.data());

  rpc_lock().lock();
  EXPECT_EQ(OkStatus(), channel.SendBuffer(output_buffer, kTestPacket));
}

TEST(Channel, OutputBuffer_PayloadDoesNotFit_ReportsError) {
  TestOutput<kReservedSize> output;
  internal::Channel channel(100, &output);

  Packet packet = kTestPacket;
  byte data[1] = {};
  packet.set_payload(data);

  EXPECT_EQ(Status::Internal(), channel.Send(packet));
}

TEST(Channel, OutputBuffer_ExtraRoom) {
  TestOutput<kReservedSize * 3> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer output_buffer = channel.AcquireBuffer();
  const std::span payload = output_buffer.payload(kTestPacket);

  EXPECT_EQ(payload.size(), output.buffer().size() - kReservedSize);
  EXPECT_EQ(output.buffer().data() + kReservedSize, payload.data());

  rpc_lock().lock();
  EXPECT_EQ(OkStatus(), channel.SendBuffer(output_buffer, kTestPacket));
}

TEST(Channel, OutputBuffer_ReturnsStatusFromChannelOutputSend) {
  TestOutput<kReservedSize * 3> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer output_buffer = channel.AcquireBuffer();
  output.set_send_status(Status::Aborted());

  rpc_lock().lock();
  EXPECT_EQ(Status::Aborted(), channel.SendBuffer(output_buffer, kTestPacket));
}

TEST(Channel, OutputBuffer_Contains_FalseWhenEmpty) {
  Channel::OutputBuffer buffer;
  EXPECT_FALSE(buffer.Contains({}));

  std::byte data[1];
  EXPECT_FALSE(buffer.Contains(data));
}

TEST(Channel, OutputBuffer_Contains_TrueIfContained) {
  TestOutput<16> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer buffer = channel.AcquireBuffer();
  EXPECT_TRUE(buffer.Contains(output.buffer()));

  rpc_lock().lock();
  channel.Release(buffer);
}

TEST(Channel, OutputBuffer_Contains_FalseIfOutside) {
  TestOutput<16> output;
  internal::Channel channel(100, &output);

  Channel::OutputBuffer buffer = channel.AcquireBuffer();
  std::span before(output.buffer().data() - 1, 5);
  EXPECT_FALSE(buffer.Contains(before));

  std::span after(output.buffer().data() + output.buffer().size() - 1, 2);
  EXPECT_FALSE(buffer.Contains(after));

  rpc_lock().lock();
  channel.Release(buffer);
}

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