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

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

#define ASSERT_OK(status) ASSERT_EQ(OkStatus(), status)

namespace pw::protobuf {

TEST(ProtoHelper, IterateMessage) {
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // type=uint32, k=1, v=1
    0x08, 0x01,
    // type=uint32, k=2, v=2
    0x10, 0x02,
    // type=uint32, k=3, v=3
    0x18, 0x03,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  uint32_t count = 0;
  for (Message::Field field : parser) {
    ++count;
    EXPECT_EQ(field.field_number(), count);
    Uint32 value = field.As<Uint32>();
    ASSERT_OK(value.status());
    EXPECT_EQ(value.value(), count);
  }

  EXPECT_EQ(count, static_cast<uint32_t>(3));
}

TEST(ProtoHelper, MessageIterator) {
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // type=uint32, k=2, v=2
    0x10, 0x02,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  Message::iterator iter = parser.begin();

  Message::iterator first = iter++;
  ASSERT_EQ(first, first);
  ASSERT_EQ(first->field_number(), static_cast<uint32_t>(1));
  String str = first->As<String>();
  ASSERT_OK(str.status());
  Result<bool> cmp = str.Equal("foo 1");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());

  Message::iterator second = iter++;
  ASSERT_EQ(second, second);
  ASSERT_EQ(second->field_number(), static_cast<uint32_t>(2));
  Uint32 uint32_val = second->As<Uint32>();
  ASSERT_OK(uint32_val.status());
  ASSERT_EQ(uint32_val.value(), static_cast<uint32_t>(2));

  ASSERT_NE(first, second);
  ASSERT_NE(first, iter);
  ASSERT_NE(second, iter);
  ASSERT_EQ(iter, parser.end());
}

TEST(ProtoHelper, MessageIteratorMalformedProto) {
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a,0x05,'f','o','o',' ','1',
    // key = 0, str = "foo 2" (invalid)
    0x02,0x05,'f','o','o',' ','2',
    // key = 3, str = "bar 1"
    0x1a,0x05,'b','a','r',' ','1',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  Message::iterator iter = parser.begin();
  ASSERT_OK(iter.status());

  // Second field has invalid field number
  ASSERT_FALSE((++iter).ok());

  // Attempting to increment an invalid iterator result in it being end()
  ASSERT_EQ((++iter), parser.end());

  // Test the c++ std loop behavior.
  bool expected_ok_status[] = {true, false};
  size_t count = 0;
  for (Message::Field field : parser) {
    ASSERT_EQ(field.ok(), expected_ok_status[count++]);
  }
  // First element ok. Second element invalid. Iteration ends in the next
  // iteration.
  ASSERT_EQ(count, 2ULL);
}

TEST(ProtoHelper, InvalidMessageBeginIterator) {
  Message parser(Status::Internal());
  ASSERT_FALSE(parser.begin().ok());
  ASSERT_EQ(parser.begin(), parser.end());
}

TEST(ProtoHelper, AsProtoInteger) {
  // clang-format off
  std::uint8_t encoded_proto[] = {
      // type: int32, k = 1, val = -123
      0x08, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
      // type: uint32, k = 2, val = 123
      0x10, 0x7b,
      // type: sint32, k = 3, val = -456
      0x18, 0x8f, 0x07,
      // type: fixed32, k = 4, val = 268435457
      0x25, 0x01, 0x00, 0x00, 0x10,
      // type: sfixed32, k = 5, val = -268435457
      0x2d, 0xff, 0xff, 0xff, 0xef,
      // type: int64, k = 6, val = -1099511627776
      0x30, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe0, 0xff, 0xff, 0xff, 0x01,
      // type: uint64, k = 7, val = 1099511627776
      0x38, 0x80, 0x80, 0x80, 0x80, 0x80, 0x20,
      // type: sint64, k = 8, val = -2199023255552
      0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
      // type: fixed64, k = 9, val = 72057594037927937
      0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
      // type: sfixed64, k = 10, val = -72057594037927937
      0x51, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
      // type: float, k = 11, val = 123456.00
      0x5d, 0x00, 0x20, 0xf1, 0x47,
      // type: double, k = 12, val = -123456.789
      0x61, 0xc9, 0x76, 0xbe, 0x9f, 0x0c, 0x24, 0xfe, 0xc0,
      // type: bool, k = 13, val = true
      0x68, 0x01,
      // type: bool, k = 14, val = false
      0x70, 0x00
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  {
    Int32 value = parser.AsInt32(1);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int32_t>(-123));
  }

  {
    Uint32 value = parser.AsUint32(2);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<uint32_t>(123));
  }

  {
    Sint32 value = parser.AsSint32(3);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int32_t>(-456));
  }

  {
    Fixed32 value = parser.AsFixed32(4);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<uint32_t>(268435457));
  }

  {
    Sfixed32 value = parser.AsSfixed32(5);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int32_t>(-268435457));
  }

  {
    Int64 value = parser.AsInt64(6);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int64_t>(-1099511627776));
  }

  {
    Uint64 value = parser.AsUint64(7);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<uint64_t>(1099511627776));
  }

  {
    Sint64 value = parser.AsSint64(8);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int64_t>(-2199023255552));
  }

  {
    Fixed64 value = parser.AsFixed64(9);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<uint64_t>(72057594037927937));
  }

  {
    Sfixed64 value = parser.AsSfixed64(10);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<int64_t>(-72057594037927937));
  }

  {
    Float value = parser.AsFloat(11);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<float>(123456.00));
  }

  {
    Double value = parser.AsDouble(12);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<double>(-123456.789));
  }

  {
    Bool value = parser.AsBool(13);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<bool>(true));
  }

  {
    Bool value = parser.AsBool(14);
    ASSERT_OK(value.status());
    ASSERT_EQ(value.value(), static_cast<bool>(false));
  }
}

TEST(ProtoHelper, AsString) {
  // message {
  //   string str = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // `str`, k = 1, "string"
    0x0a, 0x06, 's', 't', 'r', 'i', 'n', 'g',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  constexpr uint32_t kFieldNumber = 1;
  String value = parser.AsString(kFieldNumber);
  ASSERT_OK(value.status());
  Result<bool> cmp = value.Equal("string");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());

  cmp = value.Equal("other");
  ASSERT_OK(cmp.status());
  ASSERT_FALSE(cmp.value());

  // The string is a prefix of the target string to compare.
  cmp = value.Equal("string and more");
  ASSERT_OK(cmp.status());
  ASSERT_FALSE(cmp.value());

  // The target string to compare is a sub prefix of this string
  cmp = value.Equal("str");
  ASSERT_OK(cmp.status());
  ASSERT_FALSE(cmp.value());
}

TEST(ProtoHelper, AsRepeatedStrings) {
  // Repeated field of string i.e.
  //
  // message RepeatedString {
  //   repeated string msg_a = 1;
  //   repeated string msg_b = 2;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 2, str = "foo 2"
    0x12, 0x05, 'f', 'o', 'o', ' ', '2',
    // key = 1, str = "bar 1"
    0x0a, 0x05, 'b', 'a', 'r', ' ', '1',
    // key = 2, str = "bar 2"
    0x12, 0x05, 'b', 'a', 'r', ' ', '2',
  };
  // clang-format on

  constexpr uint32_t kMsgAFieldNumber = 1;
  constexpr uint32_t kMsgBFieldNumber = 2;
  constexpr uint32_t kNonExistFieldNumber = 3;

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  // Field 'msg_a'
  {
    RepeatedStrings msg = parser.AsRepeatedStrings(kMsgAFieldNumber);
    std::string_view expected[] = {
        "foo 1",
        "bar 1",
    };

    size_t count = 0;
    for (String ele : msg) {
      ASSERT_OK(ele.status());
      Result<bool> res = ele.Equal(expected[count++]);
      ASSERT_OK(res.status());
      ASSERT_TRUE(res.value());
    }

    ASSERT_EQ(count, static_cast<size_t>(2));
  }

  // Field `msg_b`
  {
    RepeatedStrings msg = parser.AsRepeatedStrings(kMsgBFieldNumber);
    std::string_view expected[] = {
        "foo 2",
        "bar 2",
    };

    size_t count = 0;
    for (String ele : msg) {
      ASSERT_OK(ele.status());
      Result<bool> res = ele.Equal(expected[count++]);
      ASSERT_OK(res.status());
      ASSERT_TRUE(res.value());
    }

    ASSERT_EQ(count, static_cast<size_t>(2));
  }

  // non-existing field
  {
    RepeatedStrings msg = parser.AsRepeatedStrings(kNonExistFieldNumber);
    size_t count = 0;
    for ([[maybe_unused]] String ele : msg) {
      count++;
    }

    ASSERT_EQ(count, static_cast<size_t>(0));
  }
}

TEST(ProtoHelper, RepeatedFieldIterator) {
  // Repeated field of string i.e.
  //
  // message RepeatedString {
  //   repeated string msg = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 1, str = "bar 1"
    0x0a, 0x05, 'b', 'a', 'r', ' ', '1',
  };
  // clang-format on

  constexpr uint32_t kFieldNumber = 1;
  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));
  RepeatedStrings repeated_str = parser.AsRepeatedStrings(kFieldNumber);

  RepeatedStrings::iterator iter = repeated_str.begin();

  RepeatedStrings::iterator first = iter++;
  ASSERT_EQ(first, first);
  Result<bool> cmp = first->Equal("foo 1");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());

  RepeatedStrings::iterator second = iter++;
  ASSERT_EQ(second, second);
  cmp = second->Equal("bar 1");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());

  ASSERT_NE(first, second);
  ASSERT_NE(first, iter);
  ASSERT_NE(second, iter);
  ASSERT_EQ(iter, repeated_str.end());
}

TEST(ProtoHelper, RepeatedFieldIteratorMalformedFieldID) {
  // Repeated field of string i.e.
  //
  // message RepeatedString {
  //   repeated string msg = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 0, str = "foo 1" (invalid)
    0x02, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));
  RepeatedStrings repeated_str = parser.AsRepeatedStrings(1);

  bool expected_ok[] = {true, false};
  size_t count = 0;
  for (String s : repeated_str) {
    ASSERT_EQ(s.ok(), expected_ok[count++]);
  }
  // Iterator becomes invalid in the second iteration. Attempting to increment
  // causes it to become end(); Therefore, count should be incremented twice.
  ASSERT_EQ(count, 2ULL);
}

TEST(ProtoHelper, RepeatedFieldIteratorMalformedFieldIDBeginning) {
  // Repeated field of string i.e.
  //
  // message RepeatedString {
  //   repeated string msg = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 0, str = "foo 1" (invalid)
    0x02, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));
  RepeatedStrings repeated_str = parser.AsRepeatedStrings(1);

  bool expected_ok[] = {false};
  size_t count = 0;
  for (String s : repeated_str) {
    ASSERT_EQ(s.ok(), expected_ok[count++]);
  }
  // Iterator becomes invalid in the second iteration. Attempting to increment
  // causes it to become end(); Therefore, count should be incremented twice.
  ASSERT_EQ(count, 1ULL);
}

TEST(ProtoHelper, RepeatedFieldIteratorMalformedDataLoss) {
  // Repeated field of string i.e.
  //
  // message RepeatedString {
  //   repeated string msg = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // key = 1, str = "foo 1"
    0x0a, 0x05, 'f', 'o', 'o', ' ', '1',
    // key = 0, str = "foo 1" (invalid)
    0x0a, 0x10, 'f', 'o', 'o', ' ', '1',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));
  RepeatedStrings repeated_str = parser.AsRepeatedStrings(1);

  bool expected_ok[] = {true, false};
  size_t count = 0;
  for (String s : repeated_str) {
    ASSERT_EQ(s.ok(), expected_ok[count++]);
  }
  ASSERT_EQ(count, 2ULL);
}

TEST(ProtoHelper, AsMessage) {
  // A nested message:
  //
  // message Contact {
  //   string number = 1;
  //   string email = 2;
  // }
  //
  // message Person {
  //  Contact info = 2;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // Person.info.number = "123456", .email = "foo@email.com"
    0x12, 0x17,
    0x0a, 0x06, '1', '2', '3', '4', '5', '6',
    0x12, 0x0d, 'f', 'o', 'o', '@', 'e', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm',
  };
  // clang-format on

  constexpr uint32_t kInfoFieldNumber = 2;
  constexpr uint32_t kNumberFieldNumber = 1;
  constexpr uint32_t kEmailFieldNumber = 2;

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  Message info = parser.AsMessage(kInfoFieldNumber);
  ASSERT_OK(info.status());

  String number = info.AsString(kNumberFieldNumber);
  ASSERT_OK(number.status());
  Result<bool> cmp = number.Equal("123456");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());

  String email = info.AsString(kEmailFieldNumber);
  ASSERT_OK(email.status());
  cmp = email.Equal("foo@email.com");
  ASSERT_OK(cmp.status());
  ASSERT_TRUE(cmp.value());
}

TEST(ProtoHelper, AsRepeatedMessages) {
  // message Contact {
  //   string number = 1;
  //   string email = 2;
  // }
  //
  // message Person {
  //  repeated Contact info = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // Person.Contact.number = "12345", .email = "foo@email.com"
    0x0a, 0x16,
    0x0a, 0x05, '1', '2', '3', '4', '5',
    0x12, 0x0d, 'f', 'o', 'o', '@', 'e', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm',

    // Person.Contact.number = "67890", .email = "bar@email.com"
    0x0a, 0x16,
    0x0a, 0x05, '6', '7', '8', '9', '0',
    0x12, 0x0d, 'b', 'a', 'r', '@', 'e', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm',
  };
  // clang-format on

  constexpr uint32_t kInfoFieldNumber = 1;
  constexpr uint32_t kNumberFieldNumber = 1;
  constexpr uint32_t kEmailFieldNumber = 2;

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  RepeatedMessages messages = parser.AsRepeatedMessages(kInfoFieldNumber);
  ASSERT_OK(messages.status());

  struct {
    std::string_view number;
    std::string_view email;
  } expected[] = {
      {"12345", "foo@email.com"},
      {"67890", "bar@email.com"},
  };

  size_t count = 0;
  for (Message message : messages) {
    String number = message.AsString(kNumberFieldNumber);
    ASSERT_OK(number.status());
    Result<bool> cmp = number.Equal(expected[count].number);
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    String email = message.AsString(kEmailFieldNumber);
    ASSERT_OK(email.status());
    cmp = email.Equal(expected[count].email);
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    count++;
  }

  ASSERT_EQ(count, static_cast<size_t>(2));
}

TEST(ProtoHelper, AsStringToBytesMap) {
  // message Maps {
  //   map<string, string> map_a = 1;
  //   map<string, string> map_b = 2;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // map_a["key_bar"] = "bar_a", key = 1
    0x0a, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'b', 'a', 'r', // map key
    0x12, 0x05, 'b', 'a', 'r', '_', 'a', // map value

    // map_a["key_foo"] = "foo_a", key = 1
    0x0a, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'f', 'o', 'o',
    0x12, 0x05, 'f', 'o', 'o', '_', 'a',

    // map_b["key_foo"] = "foo_b", key = 2
    0x12, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'f', 'o', 'o',
    0x12, 0x05, 'f', 'o', 'o', 0x5f, 0x62,

    // map_b["key_bar"] = "bar_b", key = 2
    0x12, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'b', 'a', 'r',
    0x12, 0x05, 'b', 'a', 'r', 0x5f, 0x62,
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  {
    // Parse field 'map_a'
    constexpr uint32_t kFieldNumber = 1;
    StringMapParser<String> string_map =
        parser.AsStringToStringMap(kFieldNumber);

    String value = string_map["key_foo"];
    ASSERT_OK(value.status());
    Result<bool> cmp = value.Equal("foo_a");
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    value = string_map["key_bar"];
    ASSERT_OK(value.status());
    cmp = value.Equal("bar_a");
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    // Non-existing key
    value = string_map["non-existing"];
    ASSERT_EQ(value.status(), Status::NotFound());
  }

  {
    // Parse field 'map_b'
    constexpr uint32_t kFieldNumber = 2;
    StringMapParser<String> string_map =
        parser.AsStringToStringMap(kFieldNumber);

    String value = string_map["key_foo"];
    ASSERT_OK(value.status());
    Result<bool> cmp = value.Equal("foo_b");
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    value = string_map["key_bar"];
    ASSERT_OK(value.status());
    cmp = value.Equal("bar_b");
    ASSERT_OK(cmp.status());
    ASSERT_TRUE(cmp.value());

    // Non-existing key
    value = string_map["non-existing"];
    ASSERT_EQ(value.status(), Status::NotFound());
  }
}

TEST(ProtoHelper, AsStringToMessageMap) {
  // message Contact {
  //   string number = 1;
  //   string email = 2;
  // }
  //
  // message Contacts {
  //  map<string, Contact> staffs = 1;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // staffs['bar'] = {.number = '456, .email = "bar@email.com"}
    0x0a, 0x1b,
    0x0a, 0x03, 0x62, 0x61, 0x72,
    0x12, 0x14, 0x0a, 0x03, 0x34, 0x35, 0x36, 0x12, 0x0d, 0x62, 0x61, 0x72, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,

    // staffs['foo'] = {.number = '123', .email = "foo@email.com"}
    0x0a, 0x1b,
    0x0a, 0x03, 0x66, 0x6f, 0x6f,
    0x12, 0x14, 0x0a, 0x03, 0x31, 0x32, 0x33, 0x12, 0x0d, 0x66, 0x6f, 0x6f, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
  };
  // clang-format on
  constexpr uint32_t kStaffsFieldId = 1;
  constexpr uint32_t kNumberFieldId = 1;
  constexpr uint32_t kEmailFieldId = 2;

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  StringMapParser<Message> staffs = parser.AsStringToMessageMap(kStaffsFieldId);
  ASSERT_OK(staffs.status());

  Message foo_staff = staffs["foo"];
  ASSERT_OK(foo_staff.status());
  String foo_number = foo_staff.AsString(kNumberFieldId);
  ASSERT_OK(foo_number.status());
  Result<bool> foo_number_cmp = foo_number.Equal("123");
  ASSERT_OK(foo_number_cmp.status());
  ASSERT_TRUE(foo_number_cmp.value());
  String foo_email = foo_staff.AsString(kEmailFieldId);
  ASSERT_OK(foo_email.status());
  Result<bool> foo_email_cmp = foo_email.Equal("foo@email.com");
  ASSERT_OK(foo_email_cmp.status());
  ASSERT_TRUE(foo_email_cmp.value());

  Message bar_staff = staffs["bar"];
  ASSERT_OK(bar_staff.status());
  String bar_number = bar_staff.AsString(kNumberFieldId);
  ASSERT_OK(bar_number.status());
  Result<bool> bar_number_cmp = bar_number.Equal("456");
  ASSERT_OK(bar_number_cmp.status());
  ASSERT_TRUE(bar_number_cmp.value());
  String bar_email = bar_staff.AsString(kEmailFieldId);
  ASSERT_OK(bar_email.status());
  Result<bool> bar_email_cmp = bar_email.Equal("bar@email.com");
  ASSERT_OK(bar_email_cmp.status());
  ASSERT_TRUE(bar_email_cmp.value());
}

TEST(ProtoHelper, AsStringToBytesMapMalformed) {
  // message Maps {
  //   map<string, string> map_a = 1;
  //   map<string, string> map_b = 2;
  // }
  // clang-format off
  std::uint8_t encoded_proto[] = {
    // map_a["key_bar"] = "bar_a", key = 1
    0x0a, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'b', 'a', 'r', // map key
    0x12, 0x05, 'b', 'a', 'r', '_', 'a', // map value

    // map_a["key_foo"] = "foo_a", key = 0 (invalid)
    0x02, 0x10,
    0x0a, 0x07, 'k', 'e', 'y', '_', 'f', 'o', 'o',
    0x12, 0x05, 'f', 'o', 'o', '_', 'a',
  };
  // clang-format on

  stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
  Message parser = Message(reader, sizeof(encoded_proto));

  // Parse field 'map_a'
  constexpr uint32_t kFieldNumber = 1;
  StringMapParser<String> string_map = parser.AsStringToStringMap(kFieldNumber);

  bool expected_ok_status[] = {true, false};
  size_t count = 0;
  for (StringToStringMapEntry entry : string_map) {
    ASSERT_EQ(entry.ok(), expected_ok_status[count]);
    ASSERT_EQ(entry.Key().ok(), expected_ok_status[count]);
    ASSERT_EQ(entry.Value().ok(), expected_ok_status[count]);
    count++;
  }
  ASSERT_EQ(count, 2ULL);
}

}  // namespace pw::protobuf
