// 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 <array>
#include <span>
#include <stdexcept>
#include <string_view>

#include "gtest/gtest.h"
#include "pw_bytes/span.h"
#include "pw_containers/vector.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"
#include "pw_stream/memory_stream.h"

// These header files contain the code generated by the pw_protobuf plugin.
// They are re-generated every time the tests are built and are used by the
// tests to ensure that the interface remains consistent.
//
// The purpose of the tests in this file is primarily to verify that the
// generated C++ interface is valid rather than the correctness of the
// low-level encoder.
#include "pw_protobuf_test_protos/full_test.pwpb.h"
#include "pw_protobuf_test_protos/importer.pwpb.h"
#include "pw_protobuf_test_protos/non_pw_package.pwpb.h"
#include "pw_protobuf_test_protos/proto2.pwpb.h"
#include "pw_protobuf_test_protos/repeated.pwpb.h"

namespace pw::protobuf {
namespace {

using namespace pw::protobuf::test;

TEST(Codegen, StreamDecoder) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // pigweed.magic_number
    0x08, 0x49,
    // pigweed.ziggy
    0x10, 0xdd, 0x01,
    // pigweed.error_message
    0x2a, 0x10, 'n', 'o', 't', ' ', 'a', ' ',
    't', 'y', 'p', 'e', 'w', 'r', 'i', 't', 'e', 'r',
    // pigweed.bin
    0x40, 0x01,
    // pigweed.pigweed
    0x3a, 0x02,
    // pigweed.pigweed.status
    0x08, 0x02,
    // pigweed.proto
    0x4a, 0x56,
    // pigweed.proto.bin
    0x10, 0x00,
    // pigweed.proto.pigweed_pigweed_bin
    0x18, 0x00,
    // pigweed.proto.pigweed_protobuf_bin
    0x20, 0x01,
    // pigweed.proto.meta
    0x2a, 0x0f,
    // pigweed.proto.meta.file_name
    0x0a, 0x0b, '/', 'e', 't', 'c', '/', 'p', 'a', 's', 's', 'w', 'd',
    // pigweed.proto.meta.status
    0x10, 0x02,
    // pigweed.proto.nested_pigweed
    0x0a, 0x3d,
    // pigweed.proto.nested_pigweed.error_message
    0x2a, 0x10, 'h', 'e', 'r', 'e', ' ', 'w', 'e', ' ',
    'g', 'o', ' ', 'a', 'g', 'a', 'i', 'n',
    // pigweed.proto.nested_pigweed.magic_number
    0x08, 0xe8, 0x04,
    // pigweed.proto.nested_pigweed.device_info
    0x32, 0x26,
    // pigweed.proto.nested_pigweed.device_info.attributes[0]
    0x22, 0x10,
    // pigweed.proto.nested_pigweed.device_info.attributes[0].key
    0x0a, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n',
    // pigweed.proto.nested_pigweed.device_info.attributes[0].value
    0x12, 0x05, '5', '.', '3', '.', '1',
    // pigweed.proto.nested_pigweed.device_info.attributes[1]
    0x22, 0x10,
    // pigweed.proto.nested_pigweed.device_info.attributes[1].key
    0x0a, 0x04, 'c', 'h', 'i', 'p',
    // pigweed.proto.nested_pigweed.device_info.attributes[1].value
    0x12, 0x08, 'l', 'e', 'f', 't', '-', 's', 'o', 'c',
    // pigweed.proto.nested_pigweed.device_info.status
    0x18, 0x03,
    // pigweed.id[0]
    0x52, 0x02,
    // pigweed.id[0].id
    0x08, 0x31,
    // pigweed.id[1]
    0x52, 0x02,
    // pigweed.id[1].id
    0x08, 0x39,
    // pigweed.id[2]
    0x52, 0x02,
    // pigweed.id[2].id
    0x08, 0x4b,
    // pigweed.id[3]
    0x52, 0x02,
    // pigweed.id[3].id
    0x08, 0x67,
    // pigweed.id[4]
    0x52, 0x03,
    // pigweed.id[4].id
    0x08, 0x8d, 0x01

  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  Pigweed::StreamDecoder pigweed(reader);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::MAGIC_NUMBER);
  Result<uint32_t> magic_number = pigweed.ReadMagicNumber();
  EXPECT_EQ(magic_number.status(), OkStatus());
  EXPECT_EQ(magic_number.value(), 0x49u);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::ZIGGY);
  Result<int32_t> ziggy = pigweed.ReadZiggy();
  EXPECT_EQ(ziggy.status(), OkStatus());
  EXPECT_EQ(ziggy.value(), -111);

  constexpr std::string_view kExpectedErrorMessage{"not a typewriter"};

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::ERROR_MESSAGE);
  std::array<char, 32> error_message{};
  StatusWithSize error_message_status = pigweed.ReadErrorMessage(error_message);
  EXPECT_EQ(error_message_status.status(), OkStatus());
  EXPECT_EQ(error_message_status.size(), kExpectedErrorMessage.size());
  EXPECT_EQ(std::memcmp(error_message.data(),
                        kExpectedErrorMessage.data(),
                        kExpectedErrorMessage.size()),
            0);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::BIN);
  Result<Pigweed::Protobuf::Binary> bin = pigweed.ReadBin();
  EXPECT_EQ(bin.status(), OkStatus());
  EXPECT_EQ(bin.value(), Pigweed::Protobuf::Binary::ZERO);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::PIGWEED);
  {
    Pigweed::Pigweed::StreamDecoder pigweed_pigweed =
        pigweed.GetPigweedDecoder();

    EXPECT_EQ(pigweed_pigweed.Next(), OkStatus());
    EXPECT_EQ(pigweed_pigweed.Field().value(),
              Pigweed::Pigweed::Fields::STATUS);
    Result<Bool> pigweed_status = pigweed_pigweed.ReadStatus();
    EXPECT_EQ(pigweed_status.status(), OkStatus());
    EXPECT_EQ(pigweed_status.value(), Bool::FILE_NOT_FOUND);

    EXPECT_EQ(pigweed_pigweed.Next(), Status::OutOfRange());
  }

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::PROTO);
  {
    Proto::StreamDecoder proto = pigweed.GetProtoDecoder();

    EXPECT_EQ(proto.Next(), OkStatus());
    EXPECT_EQ(proto.Field().value(), Proto::Fields::BIN);
    Result<Proto::Binary> proto_bin = proto.ReadBin();
    EXPECT_EQ(proto_bin.status(), OkStatus());
    EXPECT_EQ(proto_bin.value(), Proto::Binary::OFF);

    EXPECT_EQ(proto.Next(), OkStatus());
    EXPECT_EQ(proto.Field().value(), Proto::Fields::PIGWEED_PIGWEED_BIN);
    Result<Pigweed::Pigweed::Binary> proto_pigweed_bin =
        proto.ReadPigweedPigweedBin();
    EXPECT_EQ(proto_pigweed_bin.status(), OkStatus());
    EXPECT_EQ(proto_pigweed_bin.value(), Pigweed::Pigweed::Binary::ZERO);

    EXPECT_EQ(proto.Next(), OkStatus());
    EXPECT_EQ(proto.Field().value(), Proto::Fields::PIGWEED_PROTOBUF_BIN);
    Result<Pigweed::Protobuf::Binary> proto_protobuf_bin =
        proto.ReadPigweedProtobufBin();
    EXPECT_EQ(proto_protobuf_bin.status(), OkStatus());
    EXPECT_EQ(proto_protobuf_bin.value(), Pigweed::Protobuf::Binary::ZERO);

    EXPECT_EQ(proto.Next(), OkStatus());
    EXPECT_EQ(proto.Field().value(), Proto::Fields::META);
    {
      Pigweed::Protobuf::Compiler::StreamDecoder meta = proto.GetMetaDecoder();

      constexpr std::string_view kExpectedFileName{"/etc/passwd"};

      EXPECT_EQ(meta.Next(), OkStatus());
      EXPECT_EQ(meta.Field().value(),
                Pigweed::Protobuf::Compiler::Fields::FILE_NAME);
      std::array<char, 32> meta_file_name{};
      StatusWithSize meta_file_name_status = meta.ReadFileName(meta_file_name);
      EXPECT_EQ(meta_file_name_status.status(), OkStatus());
      EXPECT_EQ(meta_file_name_status.size(), kExpectedFileName.size());
      EXPECT_EQ(std::memcmp(meta_file_name.data(),
                            kExpectedFileName.data(),
                            kExpectedFileName.size()),
                0);

      EXPECT_EQ(meta.Next(), OkStatus());
      EXPECT_EQ(meta.Field().value(),
                Pigweed::Protobuf::Compiler::Fields::STATUS);
      Result<Pigweed::Protobuf::Compiler::Status> meta_status =
          meta.ReadStatus();
      EXPECT_EQ(meta_status.status(), OkStatus());
      EXPECT_EQ(meta_status.value(),
                Pigweed::Protobuf::Compiler::Status::FUBAR);

      EXPECT_EQ(meta.Next(), Status::OutOfRange());
    }

    EXPECT_EQ(proto.Next(), OkStatus());
    EXPECT_EQ(proto.Field().value(), Proto::Fields::PIGWEED);
    {
      Pigweed::StreamDecoder proto_pigweed = proto.GetPigweedDecoder();

      constexpr std::string_view kExpectedProtoErrorMessage{"here we go again"};

      EXPECT_EQ(proto_pigweed.Next(), OkStatus());
      EXPECT_EQ(proto_pigweed.Field().value(), Pigweed::Fields::ERROR_MESSAGE);
      std::array<char, 32> proto_pigweed_error_message{};
      StatusWithSize proto_pigweed_error_message_status =
          proto_pigweed.ReadErrorMessage(proto_pigweed_error_message);
      EXPECT_EQ(proto_pigweed_error_message_status.status(), OkStatus());
      EXPECT_EQ(proto_pigweed_error_message_status.size(),
                kExpectedProtoErrorMessage.size());
      EXPECT_EQ(std::memcmp(proto_pigweed_error_message.data(),
                            kExpectedProtoErrorMessage.data(),
                            kExpectedProtoErrorMessage.size()),
                0);

      EXPECT_EQ(proto_pigweed.Next(), OkStatus());
      EXPECT_EQ(proto_pigweed.Field().value(), Pigweed::Fields::MAGIC_NUMBER);
      Result<uint32_t> proto_pigweed_magic_number =
          proto_pigweed.ReadMagicNumber();
      EXPECT_EQ(proto_pigweed_magic_number.status(), OkStatus());
      EXPECT_EQ(proto_pigweed_magic_number.value(), 616u);

      EXPECT_EQ(proto_pigweed.Next(), OkStatus());
      EXPECT_EQ(proto_pigweed.Field().value(), Pigweed::Fields::DEVICE_INFO);
      {
        DeviceInfo::StreamDecoder device_info =
            proto_pigweed.GetDeviceInfoDecoder();

        EXPECT_EQ(device_info.Next(), OkStatus());
        EXPECT_EQ(device_info.Field().value(), DeviceInfo::Fields::ATTRIBUTES);
        {
          KeyValuePair::StreamDecoder key_value_pair =
              device_info.GetAttributesDecoder();

          constexpr std::string_view kExpectedKey{"version"};
          constexpr std::string_view kExpectedValue{"5.3.1"};

          EXPECT_EQ(key_value_pair.Next(), OkStatus());
          EXPECT_EQ(key_value_pair.Field().value(), KeyValuePair::Fields::KEY);
          std::array<char, 32> key{};
          StatusWithSize key_status = key_value_pair.ReadKey(key);
          EXPECT_EQ(key_status.status(), OkStatus());
          EXPECT_EQ(key_status.size(), kExpectedKey.size());
          EXPECT_EQ(
              std::memcmp(key.data(), kExpectedKey.data(), kExpectedKey.size()),
              0);

          EXPECT_EQ(key_value_pair.Next(), OkStatus());
          EXPECT_EQ(key_value_pair.Field().value(),
                    KeyValuePair::Fields::VALUE);
          std::array<char, 32> value{};
          StatusWithSize value_status = key_value_pair.ReadValue(value);
          EXPECT_EQ(value_status.status(), OkStatus());
          EXPECT_EQ(value_status.size(), kExpectedValue.size());
          EXPECT_EQ(
              std::memcmp(
                  value.data(), kExpectedValue.data(), kExpectedValue.size()),
              0);

          EXPECT_EQ(key_value_pair.Next(), Status::OutOfRange());
        }

        EXPECT_EQ(device_info.Next(), OkStatus());
        EXPECT_EQ(device_info.Field().value(), DeviceInfo::Fields::ATTRIBUTES);
        {
          KeyValuePair::StreamDecoder key_value_pair =
              device_info.GetAttributesDecoder();

          constexpr std::string_view kExpectedKey{"chip"};
          constexpr std::string_view kExpectedValue{"left-soc"};

          EXPECT_EQ(key_value_pair.Next(), OkStatus());
          EXPECT_EQ(key_value_pair.Field().value(), KeyValuePair::Fields::KEY);
          std::array<char, 32> key{};
          StatusWithSize key_status = key_value_pair.ReadKey(key);
          EXPECT_EQ(key_status.status(), OkStatus());
          EXPECT_EQ(key_status.size(), kExpectedKey.size());
          EXPECT_EQ(
              std::memcmp(key.data(), kExpectedKey.data(), kExpectedKey.size()),
              0);

          EXPECT_EQ(key_value_pair.Next(), OkStatus());
          EXPECT_EQ(key_value_pair.Field().value(),
                    KeyValuePair::Fields::VALUE);
          std::array<char, 32> value{};
          StatusWithSize value_status = key_value_pair.ReadValue(value);
          EXPECT_EQ(value_status.status(), OkStatus());
          EXPECT_EQ(value_status.size(), kExpectedValue.size());
          EXPECT_EQ(
              std::memcmp(
                  value.data(), kExpectedValue.data(), kExpectedValue.size()),
              0);

          EXPECT_EQ(key_value_pair.Next(), Status::OutOfRange());
        }

        EXPECT_EQ(device_info.Next(), OkStatus());
        EXPECT_EQ(device_info.Field().value(), DeviceInfo::Fields::STATUS);
        Result<DeviceInfo::DeviceStatus> device_info_status =
            device_info.ReadStatus();
        EXPECT_EQ(device_info_status.status(), OkStatus());
        EXPECT_EQ(device_info_status.value(), DeviceInfo::DeviceStatus::PANIC);

        EXPECT_EQ(device_info.Next(), Status::OutOfRange());
      }

      EXPECT_EQ(proto_pigweed.Next(), Status::OutOfRange());
    }

    EXPECT_EQ(proto.Next(), Status::OutOfRange());
  }

  for (int i = 0; i < 5; ++i) {
    EXPECT_EQ(pigweed.Next(), OkStatus());
    EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::ID);

    Proto::ID::StreamDecoder id = pigweed.GetIdDecoder();

    EXPECT_EQ(id.Next(), OkStatus());
    EXPECT_EQ(id.Field().value(), Proto::ID::Fields::ID);
    Result<uint32_t> id_id = id.ReadId();
    EXPECT_EQ(id_id.status(), OkStatus());
    EXPECT_EQ(id_id.value(), 5u * i * i + 3 * i + 49);

    EXPECT_EQ(id.Next(), Status::OutOfRange());
  }

  EXPECT_EQ(pigweed.Next(), Status::OutOfRange());
}

TEST(Codegen, ResourceExhausted) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // pigweed.error_message
    0x2a, 0x10, 'n', 'o', 't', ' ', 'a', ' ',
    't', 'y', 'p', 'e', 'w', 'r', 'i', 't', 'e', 'r',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  Pigweed::StreamDecoder pigweed(reader);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::ERROR_MESSAGE);
  std::array<char, 8> error_message{};
  StatusWithSize error_message_status = pigweed.ReadErrorMessage(error_message);
  EXPECT_EQ(error_message_status.status(), Status::ResourceExhausted());
  EXPECT_EQ(error_message_status.size(), 0u);

  EXPECT_EQ(pigweed.Next(), Status::OutOfRange());
}

TEST(Codegen, BytesReader) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // pigweed.error_message
    0x2a, 0x10, 'n', 'o', 't', ' ', 'a', ' ',
    't', 'y', 'p', 'e', 'w', 'r', 'i', 't', 'e', 'r',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  Pigweed::StreamDecoder pigweed(reader);

  constexpr std::string_view kExpectedErrorMessage{"not a typewriter"};

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::ERROR_MESSAGE);
  {
    StreamDecoder::BytesReader bytes_reader = pigweed.GetErrorMessageReader();
    EXPECT_EQ(bytes_reader.field_size(), kExpectedErrorMessage.size());

    std::array<std::byte, 32> error_message{};
    Result<ByteSpan> result = bytes_reader.Read(error_message);
    EXPECT_EQ(result.status(), OkStatus());
    EXPECT_EQ(result.value().size(), kExpectedErrorMessage.size());
    EXPECT_EQ(std::memcmp(result.value().data(),
                          kExpectedErrorMessage.data(),
                          kExpectedErrorMessage.size()),
              0);

    result = bytes_reader.Read(error_message);
    EXPECT_EQ(result.status(), Status::OutOfRange());
  }

  EXPECT_EQ(pigweed.Next(), Status::OutOfRange());
}

TEST(Codegen, Enum) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // pigweed.bin (valid value)
    0x40, 0x01,
    // pigweed.bin (unknown value)
    0x40, 0x7f,
    // pigweed.bin (invalid value)
    0x40, 0xff,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  Pigweed::StreamDecoder pigweed(reader);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::BIN);
  Result<Pigweed::Protobuf::Binary> bin = pigweed.ReadBin();
  EXPECT_EQ(bin.status(), OkStatus());
  EXPECT_TRUE(Pigweed::Protobuf::IsValidBinary(bin.value()));
  EXPECT_EQ(bin.value(), Pigweed::Protobuf::Binary::ZERO);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::BIN);
  bin = pigweed.ReadBin();
  EXPECT_EQ(bin.status(), OkStatus());
  EXPECT_FALSE(Pigweed::Protobuf::IsValidBinary(bin.value()));
  EXPECT_EQ(static_cast<uint32_t>(bin.value()), 0x7fu);

  EXPECT_EQ(pigweed.Next(), OkStatus());
  EXPECT_EQ(pigweed.Field().value(), Pigweed::Fields::BIN);
  bin = pigweed.ReadBin();
  EXPECT_EQ(bin.status(), Status::DataLoss());
}

TEST(Codegen, ImportedEnum) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // result.status (valid value)
    0x08, 0x01,
    // result.status (unknown value)
    0x08, 0x7f,
    // result.status (invalid value)
    0x08, 0xff,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  TestResult::StreamDecoder test_result(reader);

  EXPECT_EQ(test_result.Next(), OkStatus());
  EXPECT_EQ(test_result.Field().value(), TestResult::Fields::STATUS);
  Result<imported::Status> status = test_result.ReadStatus();
  EXPECT_EQ(status.status(), OkStatus());
  EXPECT_TRUE(imported::IsValidStatus(status.value()));
  EXPECT_EQ(status.value(), imported::Status::NOT_OK);

  EXPECT_EQ(test_result.Next(), OkStatus());
  EXPECT_EQ(test_result.Field().value(), TestResult::Fields::STATUS);
  status = test_result.ReadStatus();
  EXPECT_EQ(status.status(), OkStatus());
  EXPECT_FALSE(imported::IsValidStatus(status.value()));
  EXPECT_EQ(static_cast<uint32_t>(status.value()), 0x7fu);

  EXPECT_EQ(test_result.Next(), OkStatus());
  EXPECT_EQ(test_result.Field().value(), TestResult::Fields::STATUS);
  status = test_result.ReadStatus();
  EXPECT_EQ(status.status(), Status::DataLoss());
}

TEST(CodegenRepeated, NonPackedScalar) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x08, 0x00,
    0x08, 0x10,
    0x08, 0x20,
    0x08, 0x30,
    // fixed32s[]. v={0, 16, 32, 48}
    0x35, 0x00, 0x00, 0x00, 0x00,
    0x35, 0x10, 0x00, 0x00, 0x00,
    0x35, 0x20, 0x00, 0x00, 0x00,
    0x35, 0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(repeated_test.Next(), OkStatus());
    EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);

    Result<uint32_t> result = repeated_test.ReadUint32s();
    EXPECT_EQ(result.status(), OkStatus());
    EXPECT_EQ(result.value(), i * 16u);
  }

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(repeated_test.Next(), OkStatus());
    EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);

    Result<uint32_t> result = repeated_test.ReadFixed32s();
    EXPECT_EQ(result.status(), OkStatus());
    EXPECT_EQ(result.value(), i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, NonPackedScalarVector) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x08, 0x00,
    0x08, 0x10,
    0x08, 0x20,
    0x08, 0x30,
    // fixed32s[]. v={0, 16, 32, 48}
    0x35, 0x00, 0x00, 0x00, 0x00,
    0x35, 0x10, 0x00, 0x00, 0x00,
    0x35, 0x20, 0x00, 0x00, 0x00,
    0x35, 0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  pw::Vector<uint32_t, 8> uint32s{};

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(repeated_test.Next(), OkStatus());
    EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);

    Status status = repeated_test.ReadUint32s(uint32s);
    EXPECT_EQ(status, OkStatus());
    EXPECT_EQ(uint32s.size(), i + 1u);
  }

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }

  pw::Vector<uint32_t, 8> fixed32s{};

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(repeated_test.Next(), OkStatus());
    EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);

    Status status = repeated_test.ReadFixed32s(fixed32s);
    EXPECT_EQ(status, OkStatus());
    EXPECT_EQ(fixed32s.size(), i + 1u);
  }

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(fixed32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, NonPackedVarintScalarVectorFull) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x08, 0x00,
    0x08, 0x10,
    0x08, 0x20,
    0x08, 0x30,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  pw::Vector<uint32_t, 2> uint32s{};

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  Status status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(uint32s.size(), 1u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(uint32s.size(), 2u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, Status::ResourceExhausted());
  EXPECT_EQ(uint32s.size(), 2u);

  for (int i = 0; i < 2; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }
}

TEST(CodegenRepeated, NonPackedFixedScalarVectorFull) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // fixed32s[]. v={0, 16, 32, 48}
    0x35, 0x00, 0x00, 0x00, 0x00,
    0x35, 0x10, 0x00, 0x00, 0x00,
    0x35, 0x20, 0x00, 0x00, 0x00,
    0x35, 0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  pw::Vector<uint32_t, 2> fixed32s{};

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  Status status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(fixed32s.size(), 1u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(fixed32s.size(), 2u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, Status::ResourceExhausted());
  EXPECT_EQ(fixed32s.size(), 2u);

  for (int i = 0; i < 2; ++i) {
    EXPECT_EQ(fixed32s[i], i * 16u);
  }
}

TEST(CodegenRepeated, PackedScalar) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x0a, 0x04,
    0x00,
    0x10,
    0x20,
    0x30,
    // fixed32s[]. v={0, 16, 32, 48}
    0x32, 0x10,
    0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00,
    0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  std::array<uint32_t, 8> uint32s{};
  StatusWithSize sws = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(sws.status(), OkStatus());
  EXPECT_EQ(sws.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  std::array<uint32_t, 8> fixed32s{};
  sws = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(sws.status(), OkStatus());
  EXPECT_EQ(sws.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(fixed32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, PackedVarintScalarExhausted) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x0a, 0x04,
    0x00,
    0x10,
    0x20,
    0x30,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  std::array<uint32_t, 2> uint32s{};
  StatusWithSize sws = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(sws.status(), Status::ResourceExhausted());
  EXPECT_EQ(sws.size(), 2u);

  for (int i = 0; i < 2; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }
}

TEST(CodegenRepeated, PackedFixedScalarExhausted) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // fixed32s[]. v={0, 16, 32, 48}
    0x32, 0x10,
    0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00,
    0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  std::array<uint32_t, 2> fixed32s{};
  StatusWithSize sws = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(sws.status(), Status::ResourceExhausted());
  EXPECT_EQ(sws.size(), 0u);
}

TEST(CodegenRepeated, PackedScalarVector) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x0a, 0x04,
    0x00,
    0x10,
    0x20,
    0x30,
    // fixed32s[]. v={0, 16, 32, 48}
    0x32, 0x10,
    0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00,
    0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  pw::Vector<uint32_t, 8> uint32s{};
  Status status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(uint32s.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  pw::Vector<uint32_t, 8> fixed32s{};
  status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(fixed32s.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(fixed32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, PackedVarintScalarVectorFull) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x0a, 0x04,
    0x00,
    0x10,
    0x20,
    0x30,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  pw::Vector<uint32_t, 2> uint32s{};
  Status status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, Status::ResourceExhausted());
  EXPECT_EQ(uint32s.size(), 2u);

  for (int i = 0; i < 2; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }
}

TEST(CodegenRepeated, PackedFixedScalarVectorFull) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // fixed32s[]. v={0, 16, 32, 48}
    0x32, 0x10,
    0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00,
    0x30, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  pw::Vector<uint32_t, 2> fixed32s{};
  Status status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, Status::ResourceExhausted());
  EXPECT_EQ(fixed32s.size(), 0u);
}

TEST(CodegenRepeated, PackedScalarVectorRepeated) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // uint32s[], v={0, 16, 32, 48}
    0x0a, 0x04,
    0x00,
    0x10,
    0x20,
    0x30,
    // uint32s[], v={64, 80, 96, 112}
    0x0a, 0x04,
    0x40,
    0x50,
    0x60,
    0x70,
    // fixed32s[]. v={0, 16, 32, 48}
    0x32, 0x10,
    0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00,
    0x30, 0x00, 0x00, 0x00,
    // fixed32s[]. v={64, 80, 96, 112}
    0x32, 0x10,
    0x40, 0x00, 0x00, 0x00,
    0x50, 0x00, 0x00, 0x00,
    0x60, 0x00, 0x00, 0x00,
    0x70, 0x00, 0x00, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  pw::Vector<uint32_t, 8> uint32s{};
  Status status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(uint32s.size(), 4u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::UINT32S);
  status = repeated_test.ReadUint32s(uint32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(uint32s.size(), 8u);

  for (int i = 0; i < 8; ++i) {
    EXPECT_EQ(uint32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  pw::Vector<uint32_t, 8> fixed32s{};
  status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(fixed32s.size(), 4u);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::FIXED32S);
  status = repeated_test.ReadFixed32s(fixed32s);
  EXPECT_EQ(status, OkStatus());
  EXPECT_EQ(fixed32s.size(), 8u);

  for (int i = 0; i < 8; ++i) {
    EXPECT_EQ(fixed32s[i], i * 16u);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, NonScalar) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // strings[], v={"the", "quick", "brown", "fox"}
    0x1a, 0x03, 't', 'h', 'e',
    0x1a, 0x5, 'q',  'u', 'i', 'c', 'k',
    0x1a, 0x5,  'b', 'r', 'o', 'w',  'n',
    0x1a, 0x3, 'f', 'o', 'x'
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  constexpr std::array<std::string_view, 4> kExpectedString{
      {{"the"}, {"quick"}, {"brown"}, {"fox"}}};

  for (int i = 0; i < 4; ++i) {
    EXPECT_EQ(repeated_test.Next(), OkStatus());
    EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::STRINGS);
    std::array<char, 32> string{};
    StatusWithSize sws = repeated_test.ReadStrings(string);
    EXPECT_EQ(sws.status(), OkStatus());
    EXPECT_EQ(sws.size(), kExpectedString[i].size());
    EXPECT_EQ(std::memcmp(string.data(),
                          kExpectedString[i].data(),
                          kExpectedString[i].size()),
              0);
  }

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, PackedEnum) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // enums[], v={RED, GREEN, AMBER, RED}
    0x4a, 0x04, 0x00, 0x02, 0x01, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::ENUMS);
  std::array<Enum, 4> enums{};
  StatusWithSize sws = repeated_test.ReadEnums(enums);
  EXPECT_EQ(sws.status(), OkStatus());
  ASSERT_EQ(sws.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_TRUE(IsValidEnum(enums[i]));
  }

  EXPECT_EQ(enums[0], Enum::RED);
  EXPECT_EQ(enums[1], Enum::GREEN);
  EXPECT_EQ(enums[2], Enum::AMBER);
  EXPECT_EQ(enums[3], Enum::RED);

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

TEST(CodegenRepeated, PackedEnumVector) {
  // clang-format off
  constexpr uint8_t proto_data[] = {
    // enums[], v={RED, GREEN, AMBER, RED}
    0x4a, 0x04, 0x00, 0x02, 0x01, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(proto_data)));
  RepeatedTest::StreamDecoder repeated_test(reader);

  EXPECT_EQ(repeated_test.Next(), OkStatus());
  EXPECT_EQ(repeated_test.Field().value(), RepeatedTest::Fields::ENUMS);
  pw::Vector<Enum, 4> enums{};
  Status status = repeated_test.ReadEnums(enums);
  EXPECT_EQ(status, OkStatus());
  ASSERT_EQ(enums.size(), 4u);

  for (int i = 0; i < 4; ++i) {
    EXPECT_TRUE(IsValidEnum(enums[i]));
  }

  EXPECT_EQ(enums[0], Enum::RED);
  EXPECT_EQ(enums[1], Enum::GREEN);
  EXPECT_EQ(enums[2], Enum::AMBER);
  EXPECT_EQ(enums[3], Enum::RED);

  EXPECT_EQ(repeated_test.Next(), Status::OutOfRange());
}

}  // namespace
}  // namespace pw::protobuf
