// 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 "gtest/gtest.h"
#include "pw_stream/memory_stream.h"
#include "pw_stream/stream.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(std::as_bytes(std::span{ele.key}));
    stream::MemoryReader value_reader(std::as_bytes(std::span{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(std::as_bytes(std::span{key}));
  stream::MemoryReader value_reader(std::as_bytes(std::span{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(std::as_bytes(std::span{key}));
  stream::MemoryReader value_reader(std::as_bytes(std::span{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
