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

#include <span>

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

namespace pw::protobuf {
namespace {

using stream::MemoryWriter;

// 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(StreamEncoder, 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

  std::byte encode_buffer[32];
  std::byte dest_buffer[32];
  // This writer isn't necessary, it's just the most testable way to exercise
  // a stream interface. Use a MemoryEncoder when encoding a proto directly to
  // an in-memory buffer.
  MemoryWriter writer(dest_buffer);
  StreamEncoder encoder(writer, encode_buffer);

  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), OkStatus());
  EXPECT_EQ(writer.bytes_written(), 2u);
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), OkStatus());
  EXPECT_EQ(encoder.WriteFixed64(kTestProtoCyclesField, 0xdeadbeef8badf00d),
            OkStatus());
  EXPECT_EQ(encoder.WriteFloat(kTestProtoRatioField, 1.618034), OkStatus());
  EXPECT_EQ(encoder.WriteString(kTestProtoErrorMessageField, "broken 💩"),
            OkStatus());

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result = writer.WrittenData();
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, EncodeInsufficientSpace) {
  std::byte encode_buffer[12];
  MemoryEncoder encoder(encode_buffer);

  // 2 bytes.
  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), OkStatus());
  // 2 bytes.
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), OkStatus());
  // 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::ResourceExhausted());
  // Any further write operations should fail.
  EXPECT_EQ(encoder.WriteFloat(kTestProtoRatioField, 1.618034),
            Status::ResourceExhausted());

  ASSERT_EQ(encoder.status(), Status::ResourceExhausted());
}

TEST(StreamEncoder, EncodeInvalidArguments) {
  std::byte encode_buffer[12];
  MemoryEncoder encoder(encode_buffer);

  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), OkStatus());
  // Invalid proto field numbers.
  EXPECT_EQ(encoder.WriteUint32(0, 1337), Status::InvalidArgument());

  // TODO(amontanez): Does it make sense to support this?
  // encoder.Clear();

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

  // TODO(amontanez): Does it make sense to support this?
  // encoder.Clear();

  EXPECT_EQ(encoder.WriteBool(19091, false), Status::InvalidArgument());
  ASSERT_EQ(encoder.status(), Status::InvalidArgument());
}

TEST(StreamEncoder, Nested) {
  // This is the largest complete submessage in this test.
  constexpr size_t kLargestSubmessageSize = 0x30;
  constexpr size_t kScratchBufferSize =
      MaxScratchBufferSize(kLargestSubmessageSize, 2);
  std::byte encode_buffer[kScratchBufferSize];
  std::byte dest_buffer[128];
  MemoryWriter writer(dest_buffer);
  StreamEncoder encoder(writer, encode_buffer);

  // TestProto test_proto;
  // test_proto.magic_number = 42;
  EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), OkStatus());

  {
    // NestedProto& nested_proto = test_proto.nested;
    StreamEncoder nested_proto =
        encoder.GetNestedEncoder(kTestProtoNestedField);
    // nested_proto.hello = "world";
    EXPECT_EQ(nested_proto.WriteString(kNestedProtoHelloField, "world"),
              OkStatus());

    {
      // DoubleNestedProto& double_nested_proto = nested_proto.append_pair();
      StreamEncoder double_nested_proto =
          nested_proto.GetNestedEncoder(kNestedProtoPairField);
      // double_nested_proto.key = "version";
      EXPECT_EQ(double_nested_proto.WriteString(kDoubleNestedProtoKeyField,
                                                "version"),
                OkStatus());
      // double_nested_proto.value = "2.9.1";
      EXPECT_EQ(double_nested_proto.WriteString(kDoubleNestedProtoValueField,
                                                "2.9.1"),
                OkStatus());

      EXPECT_EQ(double_nested_proto.Finalize(), OkStatus());
    }  // end DoubleNestedProto

    // nested_proto.id = 999;
    EXPECT_EQ(nested_proto.WriteUint32(kNestedProtoIdField, 999), OkStatus());

    {
      // DoubleNestedProto& double_nested_proto = nested_proto.append_pair();
      StreamEncoder double_nested_proto =
          nested_proto.GetNestedEncoder(kNestedProtoPairField);
      // double_nested_proto.key = "device";
      EXPECT_EQ(
          double_nested_proto.WriteString(kDoubleNestedProtoKeyField, "device"),
          OkStatus());
      // double_nested_proto.value = "left-soc";
      EXPECT_EQ(double_nested_proto.WriteString(kDoubleNestedProtoValueField,
                                                "left-soc"),
                OkStatus());
      // Rely on destructor for finalization.
    }  // end DoubleNestedProto

    EXPECT_EQ(nested_proto.Finalize(), OkStatus());
  }  // end NestedProto

  // test_proto.ziggy = -13;
  EXPECT_EQ(encoder.WriteSint32(kTestProtoZiggyField, -13), OkStatus());

  // 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.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.id
    0x10, 0xe7, 0x07,
    // 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

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result = ConstByteSpan(writer.data(), writer.bytes_written());
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, RepeatedField) {
  std::byte encode_buffer[32];
  MemoryEncoder 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])
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }

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

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result(encoder);
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, PackedVarint) {
  std::byte encode_buffer[32];
  MemoryEncoder encoder(encode_buffer);

  // repeated uint32 values = 1;
  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedUint32(1, values)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly

  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]

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result(encoder);
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, PackedVarintInsufficientSpace) {
  std::byte encode_buffer[8];
  MemoryEncoder encoder(encode_buffer);

  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedUint32(1, values)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly

  EXPECT_EQ(encoder.status(), Status::ResourceExhausted());
}

TEST(StreamEncoder, PackedFixed) {
  std::byte encode_buffer[32];
  MemoryEncoder encoder(encode_buffer);

  // repeated fixed32 values = 1;
  constexpr uint32_t values[] = {0, 50, 100, 150, 200};
  encoder.WritePackedFixed32(1, values)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly

  // repeated fixed64 values64 = 2;
  constexpr uint64_t values64[] = {0x0102030405060708};
  encoder.WritePackedFixed64(2, values64)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly

  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,
      0x12, 0x08, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result(encoder);
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, PackedZigzag) {
  std::byte encode_buffer[32];
  MemoryEncoder encoder(encode_buffer);

  // repeated sint32 values = 1;
  constexpr int32_t values[] = {-100, -25, -1, 0, 1, 25, 100};
  encoder.WritePackedSint32(1, values)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly

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

  ASSERT_EQ(encoder.status(), OkStatus());
  ConstByteSpan result(encoder);
  EXPECT_EQ(result.size(), sizeof(encoded_proto));
  EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)),
            0);
}

TEST(StreamEncoder, ParentUnavailable) {
  std::byte encode_buffer[32];
  MemoryEncoder parent(encode_buffer);
  {
    StreamEncoder child = parent.GetNestedEncoder(kTestProtoNestedField);
    ASSERT_EQ(parent.status(), Status::Unavailable());
    ASSERT_EQ(child.status(), OkStatus());
  }
  ASSERT_EQ(parent.status(), OkStatus());
}

TEST(StreamEncoder, NestedEncoderRequiresBuffer) {
  MemoryEncoder parent((ByteSpan()));
  {
    StreamEncoder child = parent.GetNestedEncoder(kTestProtoNestedField);

    ASSERT_EQ(child.status(), Status::ResourceExhausted());
  }
  ASSERT_EQ(parent.status(), Status::ResourceExhausted());
}

TEST(StreamEncoder, WriteTooBig) {
  constexpr size_t kTempBufferSize = 32;
  constexpr size_t kWriteSize = 2;
  std::byte encode_buffer[32];
  MemoryEncoder encoder(encode_buffer);
  // Each write is 2 bytes. Ensure we can write 16 times.
  for (size_t i = 0; i < kTempBufferSize; i += kWriteSize) {
    ASSERT_EQ(encoder.WriteUint32(1, 12), OkStatus());
  }
  ASSERT_EQ(encoder.size(), kTempBufferSize);
  ASSERT_EQ(encoder.WriteUint32(1, 12), Status::ResourceExhausted());
}

TEST(StreamEncoder, EmptyChildWrites) {
  std::byte encode_buffer[32];
  MemoryEncoder parent(encode_buffer);
  { StreamEncoder child = parent.GetNestedEncoder(kTestProtoNestedField); }
  ASSERT_EQ(parent.status(), OkStatus());
  const size_t kExpectedSize =
      varint::EncodedSize(
          MakeKey(kTestProtoNestedField, WireType::kDelimited)) +
      varint::EncodedSize(0);
  ASSERT_EQ(parent.size(), kExpectedSize);
}

TEST(StreamEncoder, ChildUnavailableAfterFinalize) {
  std::byte encode_buffer[32];
  MemoryEncoder parent(encode_buffer);
  {
    StreamEncoder child = parent.GetNestedEncoder(kTestProtoNestedField);
    child.Finalize().IgnoreError();  // TODO(pwbug/387): Handle Status properly
    ASSERT_EQ(child.status(), Status::Unavailable());
  }
}

TEST(StreamEncoder, NestedStatusPropagates) {
  std::byte encode_buffer[32];
  MemoryEncoder parent(encode_buffer);
  {
    StreamEncoder child = parent.GetNestedEncoder(kTestProtoNestedField);
    ASSERT_EQ(child.WriteUint32(0, 0), Status::InvalidArgument());
  }
  ASSERT_EQ(parent.status(), Status::InvalidArgument());
}

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