// Copyright 2026 Google LLC
//
// 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 <memory>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"  // IWYU pragma: keep
#include "absl/status/status_matchers.h"
#include "cbor/cbor.h"
#include "cbor/options.h"
#include "cbor/test/external.pb.h"
#include "cbor/test/migrated.cbor.h"  // IWYU pragma: keep
#include "cbor/test/test.cbor.h"
#include "cbor/test/test.pb.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace cbor_test {
namespace {

using ::testing::Eq;

TEST(CborGeneratorTest, RoundTrip) {
  TestMessage msg;
  msg.set_name("hello");
  msg.set_version(1);

  // Serialize to CBOR map
  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);

  auto map = std::move(map_or.value());
  ASSERT_NE(map, nullptr);

  // Deserialize from CBOR map
  TestMessage parsed_msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &parsed_msg);
  ABSL_ASSERT_OK(status);

  EXPECT_EQ(parsed_msg.name(), "hello");
  EXPECT_EQ(parsed_msg.version(), 1);
}

TEST(CborGeneratorTest, ComplexRoundTrip) {
  ComplexMessage msg;
  msg.set_int32_field(10);
  msg.set_int64_field(20);
  msg.set_uint32_field(30);
  msg.set_uint64_field(40);
  msg.set_string_field("test_string");
  msg.set_bytes_field("test_bytes");
  msg.set_bool_field(true);
  msg.set_float_field(1.5f);
  msg.set_double_field(2.5);

  msg.add_repeated_int32(100);
  msg.add_repeated_int32(200);
  msg.add_repeated_string("item1");
  msg.add_repeated_string("item2");

  msg.mutable_nested()->set_value("nested_val");
  msg.add_repeated_nested()->set_value("rn1");
  msg.add_repeated_nested()->set_value("rn2");

  msg.add_repeated_bytes("b1");
  msg.add_repeated_bytes("b2");

  msg.add_repeated_string_array("s1");
  msg.add_repeated_string_array("s2");

  msg.add_repeated_int64(2000000000L);
  msg.add_repeated_int64(3000000000L);

  msg.add_repeated_uint32(300);
  msg.add_repeated_uint32(400);

  msg.add_repeated_uint64(4000000000L);
  msg.add_repeated_uint64(5000000000L);

  msg.add_repeated_bool(true);
  msg.add_repeated_bool(false);

  msg.add_repeated_float(1.5f);
  msg.add_repeated_float(2.5f);

  msg.add_repeated_double(3.5);
  msg.add_repeated_double(4.5);

  msg.set_read_only_field("ro");
  msg.set_write_only_field("wo");
  msg.set_skip_field("skip");
  msg.mutable_external_field()->set_external_value("ext_val");

  // Serialize to CBOR map
  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);

  auto map = std::move(map_or.value());
  ASSERT_NE(map, nullptr);

  // Deserialize from CBOR map
  ComplexMessage parsed_msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &parsed_msg);
  ABSL_ASSERT_OK(status);

  EXPECT_EQ(parsed_msg.int32_field(), 10);
  EXPECT_EQ(parsed_msg.int64_field(), 20);
  EXPECT_EQ(parsed_msg.uint32_field(), 30);
  EXPECT_EQ(parsed_msg.uint64_field(), 40);
  EXPECT_EQ(parsed_msg.string_field(), "test_string");
  EXPECT_EQ(parsed_msg.bytes_field(), "test_bytes");
  EXPECT_EQ(parsed_msg.bool_field(), true);
  EXPECT_FLOAT_EQ(parsed_msg.float_field(), 1.5f);
  EXPECT_DOUBLE_EQ(parsed_msg.double_field(), 2.5);

  ASSERT_EQ(parsed_msg.repeated_int32_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_int32(0), 100);
  EXPECT_EQ(parsed_msg.repeated_int32(1), 200);

  ASSERT_EQ(parsed_msg.repeated_string_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_string(0), "item1");
  EXPECT_EQ(parsed_msg.repeated_string(1), "item2");

  EXPECT_EQ(parsed_msg.nested().value(), "nested_val");

  ASSERT_EQ(parsed_msg.repeated_nested_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_nested(0).value(), "rn1");
  EXPECT_EQ(parsed_msg.repeated_nested(1).value(), "rn2");

  ASSERT_EQ(parsed_msg.repeated_bytes_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_bytes(0), "b1");
  EXPECT_EQ(parsed_msg.repeated_bytes(1), "b2");

  ASSERT_EQ(parsed_msg.repeated_string_array_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_string_array(0), "s1");
  EXPECT_EQ(parsed_msg.repeated_string_array(1), "s2");

  ASSERT_EQ(parsed_msg.repeated_int64_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_int64(0), 2000000000L);
  EXPECT_EQ(parsed_msg.repeated_int64(1), 3000000000L);

  ASSERT_EQ(parsed_msg.repeated_uint32_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_uint32(0), 300);
  EXPECT_EQ(parsed_msg.repeated_uint32(1), 400);

  ASSERT_EQ(parsed_msg.repeated_uint64_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_uint64(0), 4000000000L);
  EXPECT_EQ(parsed_msg.repeated_uint64(1), 5000000000L);

  ASSERT_EQ(parsed_msg.repeated_bool_size(), 2);
  EXPECT_EQ(parsed_msg.repeated_bool(0), true);
  EXPECT_EQ(parsed_msg.repeated_bool(1), false);

  ASSERT_EQ(parsed_msg.repeated_float_size(), 2);
  EXPECT_FLOAT_EQ(parsed_msg.repeated_float(0), 1.5f);
  EXPECT_FLOAT_EQ(parsed_msg.repeated_float(1), 2.5f);

  ASSERT_EQ(parsed_msg.repeated_double_size(), 2);
  EXPECT_DOUBLE_EQ(parsed_msg.repeated_double(0), 3.5);
  EXPECT_DOUBLE_EQ(parsed_msg.repeated_double(1), 4.5);

  EXPECT_EQ(parsed_msg.read_only_field(), "");
  EXPECT_EQ(parsed_msg.write_only_field(), "");
  EXPECT_EQ(parsed_msg.skip_field(), "");
  EXPECT_EQ(parsed_msg.external_field().external_value(), "ext_val");
}

TEST(CborGeneratorTest, RequiredFieldMissing) {
  auto map = std::make_unique<cppbor::Map>();

  RequiredMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  EXPECT_THAT(status.code(), Eq(absl::StatusCode::kInvalidArgument));
}

TEST(CborGeneratorTest, RequiredFieldPresent) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("RequiredField", cppbor::Tstr("value"));

  RequiredMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  EXPECT_EQ(msg.required_field(), "value");
}

TEST(CborGeneratorTest, RequiredRepeatedFieldEmpty) {
  RequiredRepeatedMessage msg;

  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);

  auto map = std::move(map_or.value());
  ASSERT_NE(map, nullptr);

  cbor::MapView map_view(map.get());
  auto array_view = map_view.GetOptionalArray("RequiredRepeatedField");
  ASSERT_TRUE(array_view.has_value());
  EXPECT_EQ(array_view->size(), 0);
}

TEST(CborGeneratorTest, RequiredDisallowEmptyPresent) {
  auto map = std::make_unique<cppbor::Map>();
  auto array = std::make_unique<cppbor::Array>();
  array->add(cppbor::Tstr("item"));
  map->add("RequiredNonEmptyList", std::move(array));

  RequiredDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  ASSERT_EQ(msg.required_non_empty_list_size(), 1);
  EXPECT_EQ(msg.required_non_empty_list(0), "item");
}

TEST(CborGeneratorTest, RequiredDisallowEmptyEmpty) {
  auto map = std::make_unique<cppbor::Map>();
  auto array = std::make_unique<cppbor::Array>();
  map->add("RequiredNonEmptyList", std::move(array));

  RequiredDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  EXPECT_THAT(status.code(), Eq(absl::StatusCode::kInvalidArgument));
}

TEST(CborGeneratorTest, RequiredDisallowEmptyMissing) {
  auto map = std::make_unique<cppbor::Map>();

  RequiredDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  EXPECT_THAT(status.code(), Eq(absl::StatusCode::kInvalidArgument));
}

TEST(CborGeneratorTest, OptionalDisallowEmptyPresent) {
  auto map = std::make_unique<cppbor::Map>();
  auto array = std::make_unique<cppbor::Array>();
  array->add(cppbor::Tstr("item"));
  map->add("OptionalNonEmptyList", std::move(array));

  OptionalDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  ASSERT_EQ(msg.optional_non_empty_list_size(), 1);
  EXPECT_EQ(msg.optional_non_empty_list(0), "item");
}

TEST(CborGeneratorTest, OptionalDisallowEmptyEmpty) {
  auto map = std::make_unique<cppbor::Map>();
  auto array = std::make_unique<cppbor::Array>();
  map->add("OptionalNonEmptyList", std::move(array));

  OptionalDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  EXPECT_THAT(status.code(), Eq(absl::StatusCode::kInvalidArgument));
}

TEST(CborGeneratorTest, OptionalDisallowEmptyMissing) {
  auto map = std::make_unique<cppbor::Map>();

  OptionalDisallowEmptyMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  // Proto2 does not distinguish between empty and missing, so this is 0.
  EXPECT_EQ(msg.optional_non_empty_list_size(), 0);
}

TEST(CborGeneratorTest, TypeOverrideTextString) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("TextAsBytes", cppbor::Tstr("text_value"));

  TypeOverrideMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  EXPECT_EQ(msg.text_as_bytes(), "text_value");
}

TEST(CborGeneratorTest, TypeOverrideByteString) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("BytesAsText", cppbor::Bstr("byte_value"));

  TypeOverrideMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  EXPECT_EQ(msg.bytes_as_text(), "byte_value");
}

TEST(CborGeneratorTest, TypeOverrideUint) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("UintAsInt", cppbor::Uint(42));

  TypeOverrideMessage msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &msg);
  ABSL_EXPECT_OK(status);
  EXPECT_EQ(msg.uint_as_int(), 42);
}

TEST(CborGeneratorTest, SkipValidationMissingRequired) {
  RequiredMessage msg;
  cbor::FromProtoOptions options;
  options.skip_validation = true;
  auto map_or = cbor::FromProto(msg, options);
  ABSL_EXPECT_OK(map_or);
}

TEST(CborGeneratorTest, SkipValidationEmptyRequiredDisallowEmpty) {
  RequiredDisallowEmptyMessage msg;
  cbor::FromProtoOptions options;
  options.skip_validation = true;
  auto map_or = cbor::FromProto(msg, options);
  ABSL_EXPECT_OK(map_or);
}

TEST(CborGeneratorTest, SkipValidationEmptyOptionalDisallowEmpty) {
  // Proto2 does not distinguish between empty and missing, so an empty list in
  // the proto should be considered "not present" when converting to cbor.
  OptionalDisallowEmptyMessage msg;
  cbor::FromProtoOptions options;
  options.skip_validation = true;
  auto map_or = cbor::FromProto(msg, options);
  ABSL_ASSERT_OK(map_or);
  auto map = std::move(map_or.value());
  cbor::MapView map_view(map.get());
  EXPECT_FALSE(map_view.GetOptionalArray("OptionalNonEmptyList").has_value());
}

TEST(CborGeneratorTest, FromProtoMissingRequired) {
  RequiredMessage msg;
  auto map_or = cbor::FromProto(msg);
  EXPECT_FALSE(map_or.ok());
  EXPECT_EQ(map_or.status().code(), absl::StatusCode::kInvalidArgument);
}

TEST(CborGeneratorTest, FromProtoEmptyRequiredDisallowEmpty) {
  RequiredDisallowEmptyMessage msg;
  auto map_or = cbor::FromProto(msg);
  EXPECT_FALSE(map_or.ok());
  EXPECT_EQ(map_or.status().code(), absl::StatusCode::kInvalidArgument);
}

TEST(CborGeneratorTest, FromProtoEmptyOptionalDisallowEmpty) {
  OptionalDisallowEmptyMessage msg;
  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);
  auto map = std::move(map_or.value());
  cbor::MapView map_view(map.get());
  EXPECT_FALSE(map_view.GetOptionalArray("OptionalNonEmptyList").has_value());
}

TEST(CborGeneratorTest, FromProtoNonEmptyOptionalDisallowEmpty) {
  OptionalDisallowEmptyMessage msg;
  msg.add_optional_non_empty_list("item");

  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);
  auto map = std::move(map_or.value());
  cbor::MapView map_view(map.get());
  auto list_opt = map_view.GetOptionalArray("OptionalNonEmptyList");
  ASSERT_TRUE(list_opt.has_value());
  EXPECT_EQ(list_opt->size(), 1);
  auto first_item_or = list_opt->GetString(0);
  ABSL_ASSERT_OK(first_item_or);
  EXPECT_EQ(first_item_or.value(), "item");
}

TEST(CborGeneratorTest, ImportedPublicRoundTrip) {
  ImportedPublicMessage msg;
  msg.set_public_value("imported_val");

  auto map_or = cbor::FromProto(msg);
  ABSL_ASSERT_OK(map_or);

  auto map = std::move(map_or.value());
  ASSERT_NE(map, nullptr);

  ImportedPublicMessage parsed_msg;
  cbor::MapView map_view(map.get());
  auto status = cbor::ToProto(map_view, &parsed_msg);
  ABSL_ASSERT_OK(status);

  EXPECT_EQ(parsed_msg.public_value(), "imported_val");
}

}  // namespace
}  // namespace cbor_test
