// 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/custom_namespace.cbor.h"
#include "cbor/test/custom_namespace.pb.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, CustomNamespaceRoundTrip) {
  custom_cbor::test::CustomNamespaceMessage msg;
  msg.set_name("custom_name");
  msg.set_version(42);

  // 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
  custom_cbor::test::CustomNamespaceMessage 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(), "custom_name");
  EXPECT_EQ(parsed_msg.version(), 42);
}

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
