// 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_protobuf/stream_decoder.h"

#include "gtest/gtest.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"
#include "pw_stream/memory_stream.h"
#include "pw_stream/stream.h"

namespace pw::protobuf {
namespace {
// Non-seekable wrapper for MemoryReader for testing behavior when seeking is
// not available.
class NonSeekableMemoryReader : public stream::NonSeekableReader {
 public:
  explicit NonSeekableMemoryReader(stream::MemoryReader& reader)
      : reader_(reader) {}

  size_t bytes_read() const { return reader_.bytes_read(); }
  const std::byte* data() const { return reader_.data(); }

 private:
  virtual StatusWithSize DoRead(ByteSpan destination) override {
    const pw::Result<pw::ByteSpan> result = reader_.Read(destination);
    if (!result.ok()) {
      return StatusWithSize(result.status(), 0);
    }
    return StatusWithSize(result.value().size_bytes());
  }

  stream::MemoryReader& reader_;
};

TEST(StreamDecoder, Decode) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // type=sint32, k=2, v=-13
    0x10, 0x19,
    // type=bool, k=3, v=false
    0x18, 0x00,
    // type=double, k=4, v=3.14159
    0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
    // type=fixed32, k=5, v=0xdeadbeef
    0x2d, 0xef, 0xbe, 0xad, 0xde,
    // type=string, k=6, v="Hello world"
    0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 1u);
  Result<int32_t> int32 = decoder.ReadInt32();
  ASSERT_EQ(int32.status(), OkStatus());
  EXPECT_EQ(int32.value(), 42);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 2u);
  Result<int32_t> sint32 = decoder.ReadSint32();
  ASSERT_EQ(sint32.status(), OkStatus());
  EXPECT_EQ(sint32.value(), -13);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 3u);
  Result<bool> boolean = decoder.ReadBool();
  ASSERT_EQ(boolean.status(), OkStatus());
  EXPECT_FALSE(boolean.value());

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 4u);
  Result<double> dbl = decoder.ReadDouble();
  ASSERT_EQ(dbl.status(), OkStatus());
  EXPECT_EQ(dbl.value(), 3.14159);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 5u);
  Result<uint32_t> fixed32 = decoder.ReadFixed32();
  ASSERT_EQ(fixed32.status(), OkStatus());
  EXPECT_EQ(fixed32.value(), 0xdeadbeef);

  char buffer[16];
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 6u);
  StatusWithSize sws = decoder.ReadString(buffer);
  ASSERT_EQ(sws.status(), OkStatus());
  buffer[sws.size()] = '\0';
  EXPECT_STREQ(buffer, "Hello world");

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

TEST(StreamDecoder, Decode_SkipsUnusedFields) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // type=sint32, k=2, v=-13
    0x10, 0x19,
    // type=bool, k=3, v=false
    0x18, 0x00,
    // type=double, k=4, v=3.14159
    0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
    // type=fixed32, k=5, v=0xdeadbeef
    0x2d, 0xef, 0xbe, 0xad, 0xde,
    // type=string, k=6, v="Hello world"
    0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  // Don't process any fields except for the fourth. Next should still iterate
  // correctly despite field values not being consumed.
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 4u);
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), Status::OutOfRange());
}

TEST(StreamDecoder, Decode_NonSeekable_SkipsUnusedFields) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // type=sint32, k=2, v=-13
    0x10, 0x19,
    // type=bool, k=3, v=false
    0x18, 0x00,
    // type=double, k=4, v=3.14159
    0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
    // type=fixed32, k=5, v=0xdeadbeef
    0x2d, 0xef, 0xbe, 0xad, 0xde,
    // type=string, k=6, v="Hello world"
    0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
  };
  // clang-format on

  // Test with a non-seekable memory reader
  stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
  NonSeekableMemoryReader reader(wrapped_reader);
  StreamDecoder decoder(reader);

  // Don't process any fields except for the fourth. Next should still iterate
  // correctly despite field values not being consumed.
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 4u);
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(decoder.Next(), Status::OutOfRange());
}

TEST(StreamDecoder, Decode_BadData) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // type=sint32, k=2, value... missing
    0x10,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);
  Result<int32_t> int32 = decoder.ReadInt32();
  ASSERT_EQ(int32.status(), OkStatus());
  EXPECT_EQ(int32.value(), 42);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 2u);
  EXPECT_EQ(decoder.ReadSint32().status(), Status::DataLoss());

  EXPECT_EQ(decoder.Next(), Status::DataLoss());
}

TEST(Decoder, Decode_SkipsBadFieldNumbers) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // type=int32, k=19001, v=42 (invalid field number)
    0xc8, 0xa3, 0x09, 0x2a,
    // type=bool, k=3, v=false
    0x18, 0x00,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 1u);
  Result<int32_t> int32 = decoder.ReadInt32();
  ASSERT_EQ(int32.status(), OkStatus());
  EXPECT_EQ(int32.value(), 42);

  // Bad field.
  EXPECT_EQ(decoder.Next(), Status::DataLoss());
  EXPECT_EQ(decoder.FieldNumber().status(), Status::FailedPrecondition());

  EXPECT_EQ(decoder.Next(), Status::DataLoss());
}

TEST(StreamDecoder, Decode_Nested) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,

    // Submessage (bytes) key=8, length=4
    0x32, 0x04,
    // type=uint32, k=1, v=2
    0x08, 0x02,
    // type=uint32, k=2, v=7
    0x10, 0x07,
    // End submessage

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);
  Result<int32_t> int32 = decoder.ReadInt32();
  ASSERT_EQ(int32.status(), OkStatus());
  EXPECT_EQ(int32.value(), 42);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 6u);
  {
    StreamDecoder nested = decoder.GetNestedDecoder();

    EXPECT_EQ(nested.Next(), OkStatus());
    ASSERT_EQ(*nested.FieldNumber(), 1u);
    Result<uint32_t> uint32 = nested.ReadUint32();
    ASSERT_EQ(uint32.status(), OkStatus());
    EXPECT_EQ(uint32.value(), 2u);

    EXPECT_EQ(nested.Next(), OkStatus());
    ASSERT_EQ(*nested.FieldNumber(), 2u);
    uint32 = nested.ReadUint32();
    ASSERT_EQ(uint32.status(), OkStatus());
    EXPECT_EQ(uint32.value(), 7u);

    ASSERT_EQ(nested.Next(), Status::OutOfRange());
  }

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 2u);
  Result<int32_t> sint32 = decoder.ReadSint32();
  ASSERT_EQ(sint32.status(), OkStatus());
  EXPECT_EQ(sint32.value(), -13);

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

TEST(StreamDecoder, Decode_Nested_SeeksToNextFieldOnDestruction) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,

    // Submessage (bytes) key=8, length=4
    0x32, 0x04,
    // type=uint32, k=1, v=2
    0x08, 0x02,
    // type=uint32, k=2, v=7
    0x10, 0x07,
    // End submessage

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);

  // Create a nested encoder for the nested field, but don't use it.
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 6u);
  { StreamDecoder nested = decoder.GetNestedDecoder(); }

  // The root decoder should still advance to the next field after the nested
  // decoder is closed.
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 2u);

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

TEST(StreamDecoder,
     Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,

    // Submessage (bytes) key=8, length=4
    0x32, 0x04,
    // type=uint32, k=1, v=2
    0x08, 0x02,
    // type=uint32, k=2, v=7
    0x10, 0x07,
    // End submessage

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  // Test with a non-seekable memory reader
  stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
  NonSeekableMemoryReader reader(wrapped_reader);
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);

  // Create a nested encoder for the nested field, but don't use it.
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 6u);
  { StreamDecoder nested = decoder.GetNestedDecoder(); }

  // The root decoder should still advance to the next field after the nested
  // decoder is closed.
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 2u);

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

TEST(StreamDecoder, Decode_Nested_LastField) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,

    // Submessage (bytes) key=8, length=4
    0x32, 0x04,
    // type=uint32, k=1, v=2
    0x08, 0x02,
    // type=uint32, k=2, v=7
    0x10, 0x07,
    // End submessage and proto
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);

  // Create a nested encoder for the nested field, which is the last field in
  // the root proto.
  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 6u);
  { StreamDecoder nested = decoder.GetNestedDecoder(); }

  // Root decoder should correctly terminate after the nested decoder is closed.
  EXPECT_EQ(decoder.Next(), Status::OutOfRange());
}

TEST(StreamDecoder, Decode_Nested_MultiLevel) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // Submessage key=1, length=4
    0x0a, 0x04,

    // Sub-submessage key=1, length=2
    0x0a, 0x02,
    // type=uint32, k=2, v=7
    0x10, 0x07,
    // End sub-submessage

    // End submessage
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);
  {
    StreamDecoder nested = decoder.GetNestedDecoder();

    EXPECT_EQ(nested.Next(), OkStatus());
    ASSERT_EQ(*nested.FieldNumber(), 1u);

    {
      StreamDecoder double_nested = nested.GetNestedDecoder();

      EXPECT_EQ(double_nested.Next(), OkStatus());
      ASSERT_EQ(*double_nested.FieldNumber(), 2u);
      Result<uint32_t> result = double_nested.ReadUint32();
      ASSERT_EQ(result.status(), OkStatus());
      EXPECT_EQ(result.value(), 7u);

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

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

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

TEST(StreamDecoder, Decode_Nested_InvalidField) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // Submessage key=1, length=4
    0x0a, 0x04,

    // Oops. No data!
  };

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);
  {
    StreamDecoder nested = decoder.GetNestedDecoder();
    EXPECT_EQ(nested.Next(), Status::DataLoss());
  }

  EXPECT_EQ(decoder.Next(), Status::DataLoss());
}

TEST(StreamDecoder, Decode_BytesReader) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=14
    0x0a, 0x0e,

    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 1u);
  {
    StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
    EXPECT_EQ(bytes.field_size(), 14u);

    std::byte buffer[7];
    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);

    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 9, sizeof(buffer)), 0);

    EXPECT_EQ(bytes.Read(buffer).status(), Status::OutOfRange());
  }

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

TEST(StreamDecoder, Decode_BytesReader_Seek) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=14
    0x0a, 0x0e,

    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 1u);
  {
    StreamDecoder::BytesReader bytes = decoder.GetBytesReader();

    std::byte buffer[2];

    ASSERT_EQ(bytes.Seek(3), OkStatus());

    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 5, sizeof(buffer)), 0);

    // Bad seek offset (absolute).
    ASSERT_EQ(bytes.Seek(15), Status::OutOfRange());

    // Seek back from current position.
    ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), OkStatus());

    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 3, sizeof(buffer)), 0);

    // Bad seek offset (relative).
    ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), Status::OutOfRange());

    // Seek from the end of the bytes field.
    ASSERT_EQ(bytes.Seek(-2, stream::Stream::kEnd), OkStatus());

    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 14, sizeof(buffer)), 0);

    // Bad seek offset (end).
    ASSERT_EQ(bytes.Seek(-15, stream::Stream::kEnd), Status::OutOfRange());
  }

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

TEST(StreamDecoder, Decode_BytesReader_Close) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=14
    0x0a, 0x0e,

    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d,
    // End bytes

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 1u);
  {
    // Partially consume the bytes field.
    StreamDecoder::BytesReader bytes = decoder.GetBytesReader();

    std::byte buffer[2];
    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
  }

  // Continue reading the top-level message.
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 2u);

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

TEST(StreamDecoder, Decode_BytesReader_NonSeekable_Close) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=14
    0x0a, 0x0e,

    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d,
    // End bytes

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  // Test with a non-seekable memory reader
  stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
  NonSeekableMemoryReader reader(wrapped_reader);
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 1u);
  {
    // Partially consume the bytes field.
    StreamDecoder::BytesReader bytes = decoder.GetBytesReader();

    std::byte buffer[2];
    EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
    EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
  }

  // Continue reading the top-level message.
  EXPECT_EQ(decoder.Next(), OkStatus());
  EXPECT_EQ(*decoder.FieldNumber(), 2u);

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

TEST(StreamDecoder, Decode_BytesReader_InvalidField) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=4
    0x0a, 0x04,

    // Oops. No data!
  };

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(*decoder.FieldNumber(), 1u);
  {
    StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
    EXPECT_EQ(bytes.Seek(0), Status::DataLoss());

    std::byte buffer[2];
    EXPECT_EQ(bytes.Read(buffer).status(), Status::DataLoss());
  }

  EXPECT_EQ(decoder.Next(), Status::DataLoss());
}

TEST(StreamDecoder, GetLengthDelimitedPayloadBounds) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // bytes key=1, length=14
    0x0a, 0x0e,

    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d,
    // End bytes

    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  ASSERT_EQ(OkStatus(), decoder.Next());
  Result<StreamDecoder::Bounds> field_bound =
      decoder.GetLengthDelimitedPayloadBounds();
  ASSERT_EQ(OkStatus(), field_bound.status());
  ASSERT_EQ(field_bound.value().low, 2ULL);
  ASSERT_EQ(field_bound.value().high, 16ULL);

  ASSERT_EQ(OkStatus(), decoder.Next());
  ASSERT_EQ(Status::NotFound(),
            decoder.GetLengthDelimitedPayloadBounds().status());
}

TEST(StreamDecoder, ReadDelimitedField_DoesntOverConsume) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=string, k=1, v="Hello world"
    0x0a, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
    // type=int32, k=2, v=42
    0x10, 0x2a,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader);

  ASSERT_EQ(OkStatus(), decoder.Next());

  // This buffer is much larger than the string.
  char buffer[128];
  const StatusWithSize size = decoder.ReadString(buffer);
  EXPECT_EQ(size.status(), OkStatus());
  EXPECT_EQ(size.size(), 11u);

  // Make sure we can still read the next field.
  ASSERT_EQ(OkStatus(), decoder.Next());
  const pw::Result<int32_t> result = decoder.ReadInt32();
  EXPECT_EQ(result.status(), OkStatus());
  EXPECT_EQ(result.value(), 42);
}

TEST(StreamDecoder, Decode_WithLength) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=int32, k=1, v=42
    0x08, 0x2a,
    // This field is beyond the range of the protobuf:
    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  StreamDecoder decoder(reader, /*length=*/2u);

  EXPECT_EQ(decoder.Next(), OkStatus());
  ASSERT_EQ(decoder.FieldNumber().value(), 1u);
  Result<int32_t> int32 = decoder.ReadInt32();
  ASSERT_EQ(int32.status(), OkStatus());
  EXPECT_EQ(int32.value(), 42);

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

TEST(StreamDecoder, Decode_WithLength_SkipsToEnd) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=string, k=1, v="Hello world"
    0x08, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
    // This field is beyond the range of the protobuf:
    // type=sint32, k=2, v=-13
    0x10, 0x19,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  {
    StreamDecoder decoder(reader, /*length=*/13u);

    EXPECT_EQ(decoder.Next(), OkStatus());
    ASSERT_EQ(decoder.FieldNumber().value(), 1u);
    // Don't read the value out, or advance further. Destructing the object
    // should advance to the end of the length given.
  }

  EXPECT_EQ(reader.Tell(), 13u);
}

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