// Copyright 2019 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/encoder.h"

#include "gtest/gtest.h"

namespace pw::protobuf {
namespace {

// The tests in this file use the following proto message schemas.
//
//   message TestProto {
//     uint32 magic_number = 1;
//     sint32 ziggy = 2;
//     fixed64 cycles = 3;
//     float ratio = 4;
//     string error_message = 5;
//     NestedProto nested = 6;
//   }
//
//   message NestedProto {
//     string hello = 1;
//     uint32 id = 2;
//     repeated DoubleNestedProto pair = 3;
//   }
//
//   message DoubleNestedProto {
//     string key = 1;
//     string value = 2;
//   }
//

constexpr uint32_t kTestProtoMagicNumberField = 1;
constexpr uint32_t kTestProtoZiggyField = 2;
constexpr uint32_t kTestProtoCyclesField = 3;
constexpr uint32_t kTestProtoRatioField = 4;
constexpr uint32_t kTestProtoErrorMessageField = 5;
constexpr uint32_t kTestProtoNestedField = 6;

constexpr uint32_t kNestedProtoHelloField = 1;
constexpr uint32_t kNestedProtoIdField = 2;
constexpr uint32_t kNestedProtoPairField = 3;

constexpr uint32_t kDoubleNestedProtoKeyField = 1;
constexpr uint32_t kDoubleNestedProtoValueField = 2;

TEST(Encoder, EncodePrimitives) {
  // TestProto tp;
  // tp.magic_number = 42;
  // tp.ziggy = -13;
  // tp.cycles = 0xdeadbeef8badf00d;
  // tp.ratio = 1.618034;
  // tp.error_message = "broken 💩";

  // Hand-encoded version of the above.
  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // magic_number [varint k=1]
    0x08, 0x2a,
    // ziggy [varint k=2]
    0x10, 0x19,
    // cycles [fixed64 k=3]
    0x19, 0x0d, 0xf0, 0xad, 0x8b, 0xef, 0xbe, 0xad, 0xde,
    // ratio [fixed32 k=4]
    0x25, 0xbd, 0x1b, 0xcf, 0x3f,
    // error_message [delimited k=5],
    0x2a, 0x0b, 'b', 'r', 'o', 'k', 'e', 'n', ' ',
    // poop!
    0xf0, 0x9f, 0x92, 0xa9,
  };
  // clang-format on

  uint8_t encode_buffer[32];
  NestedEncoder encoder(encode_buffer);

  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), Status::OK);
  EXPECT_EQ(encoder.WriteFixed64(kTestProtoCyclesField, 0xdeadbeef8badf00d),
            Status::OK);
  EXPECT_EQ(encoder.WriteFloat(kTestProtoRatioField, 1.618034), Status::OK);
  EXPECT_EQ(encoder.WriteString(kTestProtoErrorMessageField, "broken 💩"),
            Status::OK);

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

TEST(Encoder, EncodeInsufficientSpace) {
  uint8_t encode_buffer[12];
  NestedEncoder encoder(encode_buffer);

  // 2 bytes.
  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);
  // 2 bytes.
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), Status::OK);
  // 9 bytes; not enough space! The encoder will start writing the field but
  // should rollback when it realizes it doesn't have enough space.
  EXPECT_EQ(encoder.WriteFixed64(kTestProtoCyclesField, 0xdeadbeef8badf00d),
            Status::RESOURCE_EXHAUSTED);
  // Any further write operations should fail.
  EXPECT_EQ(encoder.WriteFloat(kTestProtoRatioField, 1.618034),
            Status::RESOURCE_EXHAUSTED);

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::RESOURCE_EXHAUSTED);
  EXPECT_EQ(encoded.size(), 0u);
}

TEST(Encoder, EncodeInvalidArguments) {
  uint8_t encode_buffer[12];
  NestedEncoder encoder(encode_buffer);

  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);
  // Invalid proto field numbers.
  EXPECT_EQ(encoder.WriteUint32(0, 1337), Status::INVALID_ARGUMENT);
  encoder.Clear();

  EXPECT_EQ(encoder.WriteString(1u << 31, "ha"), Status::INVALID_ARGUMENT);
  encoder.Clear();

  EXPECT_EQ(encoder.WriteBool(19091, false), Status::INVALID_ARGUMENT);
  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::INVALID_ARGUMENT);
  EXPECT_EQ(encoded.size(), 0u);
}

TEST(Encoder, Nested) {
  uint8_t encode_buffer[128];
  NestedEncoder<5, 10> encoder(encode_buffer);

  // TestProto test_proto;
  // test_proto.magic_number = 42;
  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);

  {
    // NestedProto& nested_proto = test_proto.nested;
    EXPECT_EQ(encoder.Push(kTestProtoNestedField), Status::OK);
    // nested_proto.hello = "world";
    EXPECT_EQ(encoder.WriteString(kNestedProtoHelloField, "world"), Status::OK);
    // nested_proto.id = 999;
    EXPECT_EQ(encoder.WriteUint32(kNestedProtoIdField, 999), Status::OK);

    {
      // DoubleNestedProto& double_nested_proto = nested_proto.append_pair();
      EXPECT_EQ(encoder.Push(kNestedProtoPairField), Status::OK);
      // double_nested_proto.key = "version";
      EXPECT_EQ(encoder.WriteString(kDoubleNestedProtoKeyField, "version"),
                Status::OK);
      // double_nested_proto.value = "2.9.1";
      EXPECT_EQ(encoder.WriteString(kDoubleNestedProtoValueField, "2.9.1"),
                Status::OK);

      EXPECT_EQ(encoder.Pop(), Status::OK);
    }  // end DoubleNestedProto

    {
      // DoubleNestedProto& double_nested_proto = nested_proto.append_pair();
      EXPECT_EQ(encoder.Push(kNestedProtoPairField), Status::OK);
      // double_nested_proto.key = "device";
      EXPECT_EQ(encoder.WriteString(kDoubleNestedProtoKeyField, "device"),
                Status::OK);
      // double_nested_proto.value = "left-soc";
      EXPECT_EQ(encoder.WriteString(kDoubleNestedProtoValueField, "left-soc"),
                Status::OK);

      EXPECT_EQ(encoder.Pop(), Status::OK);
    }  // end DoubleNestedProto

    EXPECT_EQ(encoder.Pop(), Status::OK);
  }  // end NestedProto

  // test_proto.ziggy = -13;
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), Status::OK);

  // clang-format off
  constexpr uint8_t encoded_proto[] = {
    // magic_number
    0x08, 0x2a,
    // nested header (key, size)
    0x32, 0x30,
    // nested.hello
    0x0a, 0x05, 'w', 'o', 'r', 'l', 'd',
    // nested.id
    0x10, 0xe7, 0x07,
    // nested.pair[0] header (key, size)
    0x1a, 0x10,
    // nested.pair[0].key
    0x0a, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n',
    // nested.pair[0].value
    0x12, 0x05, '2', '.', '9', '.', '1',
    // nested.pair[1] header (key, size)
    0x1a, 0x12,
    // nested.pair[1].key
    0x0a, 0x06, 'd', 'e', 'v', 'i', 'c', 'e',
    // nested.pair[1].value
    0x12, 0x08, 'l', 'e', 'f', 't', '-', 's', 'o', 'c',
    // ziggy
    0x10, 0x19
  };
  // clang-format on

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

TEST(Encoder, NestedDepthLimit) {
  uint8_t encode_buffer[128];
  NestedEncoder<2, 10> encoder(encode_buffer);

  // One level of nesting.
  EXPECT_EQ(encoder.Push(2), Status::OK);
  // Two levels of nesting.
  EXPECT_EQ(encoder.Push(1), Status::OK);
  // Three levels of nesting: error!
  EXPECT_EQ(encoder.Push(1), Status::RESOURCE_EXHAUSTED);

  // Further operations should fail.
  EXPECT_EQ(encoder.Pop(), Status::RESOURCE_EXHAUSTED);
  EXPECT_EQ(encoder.Pop(), Status::RESOURCE_EXHAUSTED);
  EXPECT_EQ(encoder.Pop(), Status::RESOURCE_EXHAUSTED);
}

TEST(Encoder, NestedBlobLimit) {
  uint8_t encode_buffer[128];
  NestedEncoder<5, 3> encoder(encode_buffer);

  // Write first blob.
  EXPECT_EQ(encoder.Push(1), Status::OK);
  EXPECT_EQ(encoder.Pop(), Status::OK);

  // Write second blob.
  EXPECT_EQ(encoder.Push(2), Status::OK);

  // Write nested third blob.
  EXPECT_EQ(encoder.Push(3), Status::OK);
  EXPECT_EQ(encoder.Pop(), Status::OK);

  // End second blob.
  EXPECT_EQ(encoder.Pop(), Status::OK);

  // Write fourth blob: error!.
  EXPECT_EQ(encoder.Push(4), Status::RESOURCE_EXHAUSTED);
  // Nothing to pop.
  EXPECT_EQ(encoder.Pop(), Status::RESOURCE_EXHAUSTED);
}

TEST(Encoder, RepeatedField) {
  uint8_t encode_buffer[32];
  NestedEncoder encoder(encode_buffer);

  // repeated uint32 values = 1;
  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  for (int i = 0; i < 5; ++i) {
    encoder.WriteUint32(1, values[i]);
  }

  constexpr uint8_t encoded_proto[] = {
      0x08, 0x00, 0x08, 0x32, 0x08, 0x64, 0x08, 0x96, 0x01, 0x08, 0xc8, 0x01};

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

TEST(Encoder, PackedVarint) {
  uint8_t encode_buffer[32];
  NestedEncoder encoder(encode_buffer);

  // repeated uint32 values = 1;
  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedUint32(1, values);

  constexpr uint8_t encoded_proto[] = {
      0x0a, 0x07, 0x00, 0x32, 0x64, 0x96, 0x01, 0xc8, 0x01};
  //  key   size  v[0]  v[1]  v[2]  v[3]        v[4]

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

TEST(Encoder, PackedVarintInsufficientSpace) {
  uint8_t encode_buffer[8];
  NestedEncoder encoder(encode_buffer);

  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedUint32(1, values);

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::RESOURCE_EXHAUSTED);
  EXPECT_EQ(encoded.size(), 0u);
}

TEST(Encoder, PackedFixed) {
  uint8_t encode_buffer[32];
  NestedEncoder encoder(encode_buffer);

  // repeated fixed32 values = 1;
  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedFixed32(1, values);

  constexpr uint8_t encoded_proto[] = {
      0x0a, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x64,
      0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00};

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

TEST(Encoder, PackedZigzag) {
  uint8_t encode_buffer[32];
  NestedEncoder encoder(encode_buffer);

  // repeated sint32 values = 1;
  constexpr int32_t values[] = {-100, -25, -1, 0, 1, 25, 100};
  encoder.WritePackedSint32(1, values);

  constexpr uint8_t encoded_proto[] = {
      0x0a, 0x09, 0xc7, 0x01, 0x31, 0x01, 0x00, 0x02, 0x32, 0xc8, 0x01};

  span<const uint8_t> encoded;
  EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
  EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
}

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