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

#include <string_view>

#include "pw_stream/memory_stream.h"
#include "pw_stream/stream.h"
#include "pw_unit_test/framework.h"

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

namespace pw::protobuf {

TEST(ProtoHelper, WriteProtoStringToBytesMapEntry) {
  // The following defines an instance of the message below:
  //
  // message Maps {
  //   map<string, string> map_a = 1;
  //   map<string, string> map_b = 2;
  // }
  //
  // where
  //
  // Maps.map_a['key_foo'] = 'foo_a'
  // Maps.map_a['key_bar'] = 'bar_a'
  //
  // Maps.map_b['key_foo'] = 'foo_b'
  // Maps.map_b['key_bar'] = 'bar_b'
  //
  // 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', '_', 'b',

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

  // Now construct the same message with WriteStringToBytesMapEntry
  std::byte dst_buffer[sizeof(encoded_proto)];
  stream::MemoryWriter writer(dst_buffer);

  const struct {
    uint32_t field_number;
    std::string_view key;
    std::string_view value;
  } kMapData[] = {
      {1, "key_bar", "bar_a"},
      {1, "key_foo", "foo_a"},
      {2, "key_foo", "foo_b"},
      {2, "key_bar", "bar_b"},
  };

  std::byte stream_pipe_buffer[1];
  for (auto ele : kMapData) {
    stream::MemoryReader key_reader(as_bytes(span<const char>{ele.key}));
    stream::MemoryReader value_reader(as_bytes(span<const char>{ele.value}));
    ASSERT_OK(WriteProtoStringToBytesMapEntry(ele.field_number,
                                              key_reader,
                                              ele.key.size(),
                                              value_reader,
                                              ele.value.size(),
                                              stream_pipe_buffer,
                                              writer));
  }

  ASSERT_EQ(memcmp(dst_buffer, encoded_proto, sizeof(dst_buffer)), 0);
}

TEST(ProtoHelper, WriteProtoStringToBytesMapEntryExceedsWriteLimit) {
  // Construct an instance of the message below:
  //
  // message Maps {
  //   map<string, string> map_a = 1;
  // }
  //
  // where
  //
  // Maps.map_a['key_bar'] = 'bar_a'. The needed buffer size is 18 in this
  // case:
  //
  // {
  //   0x0a, 0x10,
  //   0x0a, 0x07, 'k', 'e', 'y', '_', 'b', 'a', 'r',
  //   0x12, 0x05, 'b', 'a', 'r', '_', 'a',
  // }
  //
  // Use a smaller buffer.
  std::byte encode_buffer[17];
  stream::MemoryWriter writer(encode_buffer);
  constexpr uint32_t kFieldNumber = 1;
  std::string_view key = "key_bar";
  std::string_view value = "bar_a";
  stream::MemoryReader key_reader(as_bytes(span<const char>{key}));
  stream::MemoryReader value_reader(as_bytes(span<const char>{value}));
  std::byte stream_pipe_buffer[1];
  ASSERT_EQ(
      WriteProtoStringToBytesMapEntry(kFieldNumber,
                                      key_reader,
                                      key_reader.ConservativeReadLimit(),
                                      value_reader,
                                      value_reader.ConservativeReadLimit(),
                                      stream_pipe_buffer,
                                      writer),
      Status::ResourceExhausted());
}

TEST(ProtoHelper, WriteProtoStringToBytesMapEntryInvalidArgument) {
  std::byte encode_buffer[17];
  stream::MemoryWriter writer(encode_buffer);
  std::string_view key = "key_bar";
  std::string_view value = "bar_a";
  stream::MemoryReader key_reader(as_bytes(span<const char>{key}));
  stream::MemoryReader value_reader(as_bytes(span<const char>{value}));
  std::byte stream_pipe_buffer[1];

  ASSERT_EQ(
      WriteProtoStringToBytesMapEntry(19091,
                                      key_reader,
                                      key_reader.ConservativeReadLimit(),
                                      value_reader,
                                      value_reader.ConservativeReadLimit(),
                                      stream_pipe_buffer,
                                      writer),
      Status::InvalidArgument());
}

}  // namespace pw::protobuf
