// Copyright 2022 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_hdlc/encoded_size.h"

#include <array>
#include <cstddef>
#include <cstdint>

#include "gtest/gtest.h"
#include "pw_bytes/array.h"
#include "pw_hdlc/decoder.h"
#include "pw_hdlc/encoder.h"
#include "pw_hdlc/internal/encoder.h"
#include "pw_result/result.h"
#include "pw_stream/memory_stream.h"
#include "pw_varint/varint.h"

namespace pw::hdlc {
namespace {

// The varint-encoded address that represents the value that will result in the
// largest on-the-wire address after HDLC escaping.
constexpr auto kWidestVarintAddress =
    bytes::String("\x7e\x7e\x7e\x7e\x7e\x7e\x7e\x7e\x7e\x03");

// This is the decoded varint value of kWidestVarintAddress. This is
// pre-calculated as a constant to simplify tests.
constexpr uint64_t kWidestAddress = 0xbf7efdfbf7efdfbf;

// UI frames created by WriteUIFrame() will never be have an escaped control
// field, but it's technically possible for other HDLC frame types to produce
// control bytes that would need to be escaped.
constexpr size_t kEscapedControlCost = kControlSize;

// UI frames created by WriteUIFrame() will never have an escaped control
// field, but it's technically possible for other HDLC frame types to produce
// control bytes that would need to be escaped.
constexpr size_t kEscapedFcsCost = kMaxEscapedFcsSize - kFcsSize;

// Due to API limitations, the worst case buffer calculations used by the HDLC
// encoder/decoder can't be fully saturated. This constexpr value accounts for
// this by expressing the delta between the constant largest testable HDLC frame
// and the calculated worst-case-scenario.
constexpr size_t kTestLimitationsOverhead =
    kEscapedControlCost + kEscapedFcsCost;

// A payload only containing bytes that need to be escaped.
constexpr auto kFullyEscapedPayload =
    bytes::String("\x7e\x7e\x7e\x7e\x7e\x7e\x7e\x7e");

constexpr uint8_t kEscapeAddress = static_cast<uint8_t>(kFlag);
constexpr uint8_t kNoEscapeAddress = 6;

TEST(EncodedSize, Constants_WidestAddress) {
  uint64_t address = 0;
  size_t address_size =
      varint::Decode(kWidestVarintAddress, &address, kAddressFormat);
  EXPECT_EQ(address_size, 10u);
  EXPECT_EQ(address_size, kMaxAddressSize);
  EXPECT_EQ(kMaxEscapedVarintAddressSize, 19u);
  EXPECT_EQ(EscapedSize(kWidestVarintAddress), kMaxEscapedVarintAddressSize);
  EXPECT_EQ(address, kWidestAddress);
  EXPECT_EQ(varint::EncodedSize(kWidestAddress), 10u);
}

TEST(EncodedSize, EscapedSize_AllEscapeBytes) {
  EXPECT_EQ(EscapedSize(kFullyEscapedPayload), kFullyEscapedPayload.size() * 2);
}

TEST(EncodedSize, EscapedSize_NoEscapeBytes) {
  constexpr auto kData = bytes::String("\x01\x23\x45\x67\x89\xab\xcd\xef");
  EXPECT_EQ(EscapedSize(kData), kData.size());
}

TEST(EncodedSize, EscapedSize_SomeEscapeBytes) {
  constexpr auto kData = bytes::String("\x7epabu\x7d");
  EXPECT_EQ(EscapedSize(kData), kData.size() + 2);
}

TEST(EncodedSize, EscapedSize_Address) {
  EXPECT_EQ(EscapedSize(kWidestVarintAddress),
            varint::EncodedSize(kWidestAddress) * 2 - 1);
}

TEST(EncodedSize, MaxEncodedSize_Overload) {
  EXPECT_EQ(MaxEncodedFrameSize(kFullyEscapedPayload.size()),
            MaxEncodedFrameSize(kWidestAddress, kFullyEscapedPayload));
}

TEST(EncodedSize, MaxEncodedSize_EmptyPayload) {
  EXPECT_EQ(14u, MaxEncodedFrameSize(kNoEscapeAddress, {}));
  EXPECT_EQ(14u, MaxEncodedFrameSize(kEscapeAddress, {}));
}

TEST(EncodedSize, MaxEncodedSize_PayloadWithoutEscapes) {
  constexpr auto data = bytes::Array<0x00, 0x01, 0x02, 0x03>();
  EXPECT_EQ(18u, MaxEncodedFrameSize(kNoEscapeAddress, data));
  EXPECT_EQ(18u, MaxEncodedFrameSize(kEscapeAddress, data));
}

TEST(EncodedSize, MaxEncodedSize_PayloadWithOneEscape) {
  constexpr auto data = bytes::Array<0x00, 0x01, 0x7e, 0x03>();
  EXPECT_EQ(19u, MaxEncodedFrameSize(kNoEscapeAddress, data));
  EXPECT_EQ(19u, MaxEncodedFrameSize(kEscapeAddress, data));
}

TEST(EncodedSize, MaxEncodedSize_PayloadWithAllEscapes) {
  constexpr auto data = bytes::Initialized<8>(0x7e);
  EXPECT_EQ(30u, MaxEncodedFrameSize(kNoEscapeAddress, data));
  EXPECT_EQ(30u, MaxEncodedFrameSize(kEscapeAddress, data));
}

TEST(EncodedSize, MaxPayload_UndersizedFrame) {
  EXPECT_EQ(MaxSafePayloadSize(4), 0u);
}

TEST(EncodedSize, MaxPayload_SmallFrame) {
  EXPECT_EQ(MaxSafePayloadSize(128), 48u);
}

TEST(EncodedSize, MaxPayload_MediumFrame) {
  EXPECT_EQ(MaxSafePayloadSize(512), 240u);
}

TEST(EncodedSize, FrameToPayloadInversion_Odd) {
  static constexpr size_t kIntendedPayloadSize = 1234567891;
  EXPECT_EQ(MaxSafePayloadSize(MaxEncodedFrameSize(kIntendedPayloadSize)),
            kIntendedPayloadSize);
}

TEST(EncodedSize, PayloadToFrameInversion_Odd) {
  static constexpr size_t kIntendedFrameSize = 1234567891;
  EXPECT_EQ(MaxEncodedFrameSize(MaxSafePayloadSize(kIntendedFrameSize)),
            kIntendedFrameSize);
}

TEST(EncodedSize, FrameToPayloadInversion_Even) {
  static constexpr size_t kIntendedPayloadSize = 42;
  EXPECT_EQ(MaxSafePayloadSize(MaxEncodedFrameSize(kIntendedPayloadSize)),
            kIntendedPayloadSize);
}

TEST(EncodedSize, PayloadToFrameInversion_Even) {
  static constexpr size_t kIntendedFrameSize = 42;
  // Because of HDLC encoding overhead requirements, the last byte of the
  // intended frame size is wasted because it doesn't allow sufficient space for
  // another byte since said additional byte could require escaping, therefore
  // requiring a second byte to increase the safe payload size by one.
  const size_t max_frame_usage =
      MaxEncodedFrameSize(MaxSafePayloadSize(kIntendedFrameSize));
  EXPECT_EQ(max_frame_usage, kIntendedFrameSize - 1);

  // There's no further change if the inversion is done again since the frame
  // size is aligned to the reduced bounds.
  EXPECT_EQ(MaxEncodedFrameSize(MaxSafePayloadSize(max_frame_usage)),
            kIntendedFrameSize - 1);
}

TEST(EncodedSize, MostlyEscaped) {
  constexpr auto kMostlyEscapedPayload =
      bytes::String(":)\x7e\x7e\x7e\x7e\x7e\x7e\x7e\x7e");
  constexpr size_t kUnescapedBytes =
      2 * kMostlyEscapedPayload.size() - EscapedSize(kMostlyEscapedPayload);
  // Subtracting 2 should still leave enough space since two bytes won't need
  // to be escaped.
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kMostlyEscapedPayload.size()) - kUnescapedBytes;
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);
  EXPECT_EQ(kUnescapedBytes, 2u);
  EXPECT_EQ(OkStatus(),
            WriteUIFrame(kWidestAddress, kFullyEscapedPayload, writer));
  EXPECT_EQ(writer.size(),
            kExpectedMaxFrameSize - kTestLimitationsOverhead - kUnescapedBytes);
}

TEST(EncodedSize, BigAddress_SaturatedPayload) {
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kFullyEscapedPayload.size());
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);
  EXPECT_EQ(OkStatus(),
            WriteUIFrame(kWidestAddress, kFullyEscapedPayload, writer));
  EXPECT_EQ(writer.size(), kExpectedMaxFrameSize - kTestLimitationsOverhead);
}

TEST(EncodedSize, BigAddress_OffByOne) {
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kFullyEscapedPayload.size()) - 1;
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);
  EXPECT_EQ(Status::ResourceExhausted(),
            WriteUIFrame(kWidestAddress, kFullyEscapedPayload, writer));
}

TEST(EncodedSize, SmallAddress_SaturatedPayload) {
  constexpr auto kSmallerEscapedAddress = bytes::String("\x7e\x7d");
  // varint::Decode() is not constexpr, so this is a hard-coded and then runtime
  // validated.
  constexpr size_t kVarintDecodedAddress = 7999;
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kVarintDecodedAddress, kFullyEscapedPayload);
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);

  uint64_t address = 0;
  size_t address_size =
      varint::Decode(kSmallerEscapedAddress, &address, kAddressFormat);
  EXPECT_EQ(address, kVarintDecodedAddress);
  EXPECT_EQ(address_size, 2u);

  EXPECT_EQ(OkStatus(), WriteUIFrame(address, kFullyEscapedPayload, writer));
  EXPECT_EQ(writer.size(), kExpectedMaxFrameSize - kTestLimitationsOverhead);
}

TEST(EncodedSize, SmallAddress_OffByOne) {
  constexpr auto kSmallerEscapedAddress = bytes::String("\x7e\x7d");
  // varint::Decode() is not constexpr, so this is a hard-coded and then runtime
  // validated.
  constexpr size_t kVarintDecodedAddress = 7999;
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kVarintDecodedAddress, kFullyEscapedPayload);
  std::array<std::byte, kExpectedMaxFrameSize - 1> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);

  uint64_t address = 0;
  size_t address_size =
      varint::Decode(kSmallerEscapedAddress, &address, kAddressFormat);
  EXPECT_EQ(address, kVarintDecodedAddress);
  EXPECT_EQ(address_size, 2u);

  EXPECT_EQ(Status::ResourceExhausted(),
            WriteUIFrame(address, kFullyEscapedPayload, writer));
}

TEST(DecodedSize, BigAddress_SaturatedPayload) {
  constexpr auto kNoEscapePayload =
      bytes::String("The decoder needs the most space when there's no escapes");
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kNoEscapePayload.size());
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);
  EXPECT_EQ(OkStatus(),
            WriteUIFrame(kNoEscapeAddress, kNoEscapePayload, writer));

  // Allocate at least enough real buffer space.
  constexpr size_t kDecoderBufferSize =
      Decoder::RequiredBufferSizeForFrameSize(kExpectedMaxFrameSize);
  std::array<std::byte, kDecoderBufferSize> buffer;

  // Pretend the supported frame size is whatever the final size of the encoded
  // frame was.
  const size_t max_frame_size =
      Decoder::RequiredBufferSizeForFrameSize(writer.size());

  Decoder decoder(ByteSpan(buffer).first(max_frame_size));
  for (const std::byte b : writer.WrittenData()) {
    Result<Frame> frame = decoder.Process(b);
    if (frame.ok()) {
      EXPECT_EQ(frame->address(), kNoEscapeAddress);
      EXPECT_EQ(frame->data().size(), kNoEscapePayload.size());
      EXPECT_TRUE(std::memcmp(frame->data().begin(),
                              kNoEscapePayload.begin(),
                              kNoEscapePayload.size()) == 0);
    }
  }
}

TEST(DecodedSize, BigAddress_OffByOne) {
  constexpr auto kNoEscapePayload =
      bytes::String("The decoder needs the most space when there's no escapes");
  constexpr size_t kExpectedMaxFrameSize =
      MaxEncodedFrameSize(kNoEscapePayload.size());
  std::array<std::byte, kExpectedMaxFrameSize> dest_buffer;
  stream::MemoryWriter writer(dest_buffer);
  EXPECT_EQ(OkStatus(),
            WriteUIFrame(kNoEscapeAddress, kNoEscapePayload, writer));

  // Allocate at least enough real buffer space.
  constexpr size_t kDecoderBufferSize =
      Decoder::RequiredBufferSizeForFrameSize(kExpectedMaxFrameSize);
  std::array<std::byte, kDecoderBufferSize> buffer;

  // Pretend the supported frame size is whatever the final size of the encoded
  // frame was.
  const size_t max_frame_size =
      Decoder::RequiredBufferSizeForFrameSize(writer.size());

  Decoder decoder(ByteSpan(buffer).first(max_frame_size - 1));
  for (size_t i = 0; i < writer.size(); i++) {
    Result<Frame> frame = decoder.Process(writer[i]);
    if (i < writer.size() - 1) {
      EXPECT_EQ(frame.status(), Status::Unavailable());
    } else {
      EXPECT_EQ(frame.status(), Status::ResourceExhausted());
    }
  }
}

}  // namespace
}  // namespace pw::hdlc
