// 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_hdlc_lite/encoder.h"

#include <algorithm>
#include <array>
#include <cstddef>

#include "gtest/gtest.h"
#include "pw_bytes/array.h"
#include "pw_stream/memory_stream.h"

using std::byte;

namespace pw::hdlc_lite {
namespace {

constexpr byte kFlag = byte{0x7E};
constexpr byte kEscape = byte{0x7D};
constexpr uint8_t kAddress = 0x7B;  // 123
constexpr byte kControl = byte{0};

class WriteInfoFrame : public ::testing::Test {
 protected:
  WriteInfoFrame() : writer_(buffer_) {}

  stream::MemoryWriter writer_;
  std::array<byte, 32> buffer_;
};

#define EXPECT_ENCODER_WROTE(...)                                           \
  do {                                                                      \
    constexpr auto expected_data = (__VA_ARGS__);                           \
    EXPECT_EQ(writer_.bytes_written(), expected_data.size());               \
    EXPECT_EQ(                                                              \
        std::memcmp(                                                        \
            writer_.data(), expected_data.data(), writer_.bytes_written()), \
        0);                                                                 \
  } while (0)

TEST_F(WriteInfoFrame, EmptyPayload) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, std::span<byte>(), writer_));
  EXPECT_ENCODER_WROTE(
      bytes::Concat(kFlag, kAddress, kControl, uint32_t{0x8D12B2C2}, kFlag));
}

TEST_F(WriteInfoFrame, OneBytePayload) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::String("A"), writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(
      kFlag, kAddress, kControl, 'A', uint32_t{0xA63E2FA5}, kFlag));
}

TEST_F(WriteInfoFrame, OneBytePayload_Escape0x7d) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::Array<0x7d>(), writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(kFlag,
                                     kAddress,
                                     kControl,
                                     kEscape,
                                     byte{0x7d} ^ byte{0x20},
                                     uint32_t{0x89515322},
                                     kFlag));
}

TEST_F(WriteInfoFrame, OneBytePayload_Escape0x7E) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::Array<0x7e>(), writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(kFlag,
                                     kAddress,
                                     kControl,
                                     kEscape,
                                     byte{0x7e} ^ byte{0x20},
                                     uint32_t{0x10580298},
                                     kFlag));
}

TEST_F(WriteInfoFrame, AddressNeedsEscaping) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(0x7d, bytes::String("A"), writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(
      kFlag, kEscape, byte{0x5d}, kControl, 'A', uint32_t{0xA2B35317}, kFlag));
}

TEST_F(WriteInfoFrame, Crc32NeedsEscaping) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::String("abcdefg"), writer_));

  // The CRC-32 is 0x38B9FC7E, so the 0x7E must be escaped.
  constexpr auto expected_crc32 = bytes::Array<0x7d, 0x5e, 0xfc, 0xb9, 0x38>();
  EXPECT_ENCODER_WROTE(bytes::Concat(kFlag,
                                     kAddress,
                                     kControl,
                                     bytes::String("abcdefg"),
                                     expected_crc32,
                                     kFlag));
}

TEST_F(WriteInfoFrame, MultiplePayloads) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::String("ABC"), writer_));
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(kAddress, bytes::String("DEF"), writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(kFlag,
                                     kAddress,
                                     kControl,
                                     bytes::String("ABC"),
                                     uint32_t{0x14E2FC99},
                                     kFlag,
                                     kFlag,
                                     kAddress,
                                     kControl,
                                     bytes::String("DEF"),
                                     uint32_t{0x2D025C3A},
                                     kFlag));
}

TEST_F(WriteInfoFrame, PayloadWithNoEscapes) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(
                kAddress, bytes::String("123456789012345678901234"), writer_));

  // Fill the memory writer's buffer.
  ASSERT_EQ(writer_.bytes_written(), buffer_.size());

  EXPECT_ENCODER_WROTE(bytes::Concat(kFlag,
                                     kAddress,
                                     kControl,
                                     bytes::String("123456789012345678901234"),
                                     uint32_t{0x50AA35EC},
                                     kFlag));
}

TEST_F(WriteInfoFrame, PayloadWithMultipleEscapes) {
  ASSERT_EQ(Status::OK,
            WriteInformationFrame(
                kAddress,
                bytes::Array<0x7E, 0x7B, 0x61, 0x62, 0x63, 0x7D, 0x7E>(),
                writer_));
  EXPECT_ENCODER_WROTE(bytes::Concat(
      kFlag,
      kAddress,
      kControl,
      bytes::
          Array<0x7D, 0x5E, 0x7B, 0x61, 0x62, 0x63, 0x7D, 0x5D, 0x7D, 0x5E>(),
      uint32_t{0x1B8D505E},
      kFlag));
}

TEST_F(WriteInfoFrame, WriterError) {
  constexpr auto data = bytes::Initialized<sizeof(buffer_)>(0x7e);

  EXPECT_EQ(Status::RESOURCE_EXHAUSTED,
            WriteInformationFrame(kAddress, data, writer_));
}

}  // namespace
}  // namespace pw::hdlc_lite
