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

#include <memory>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"  // IWYU pragma: keep
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace cbor {
namespace {

using ::testing::Eq;

TEST(ItemViewTest, BoolType) {
  auto item = std::make_unique<cppbor::Bool>(true);
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kBool);
  auto val = view.GetBool();
  ABSL_ASSERT_OK(val);
  EXPECT_TRUE(*val);
}

TEST(ItemViewTest, FloatType) {
  auto item = std::make_unique<cppbor::Float>(1.5f);
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kFloat);
  auto val = view.GetFloat();
  ABSL_ASSERT_OK(val);
  EXPECT_FLOAT_EQ(*val, 1.5f);
}

TEST(ItemViewTest, DoubleType) {
  auto item = std::make_unique<cppbor::Double>(2.5);
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kDouble);
  auto val = view.GetDouble();
  ABSL_ASSERT_OK(val);
  EXPECT_DOUBLE_EQ(*val, 2.5);
}

TEST(ItemViewTest, Int64Type) {
  auto item = std::make_unique<cppbor::Nint>(-42);
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kInt64);
  auto val = view.GetInt64();
  ABSL_ASSERT_OK(val);
  EXPECT_EQ(*val, -42);
}

TEST(ItemViewTest, Uint64Type) {
  auto item = std::make_unique<cppbor::Uint>(42);
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kUint64);
  auto val = view.GetUint64();
  ABSL_ASSERT_OK(val);
  EXPECT_EQ(*val, 42);
}

TEST(ItemViewTest, StringType) {
  auto item = std::make_unique<cppbor::Tstr>("hello");
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kString);
  auto val = view.GetString();
  ABSL_ASSERT_OK(val);
  EXPECT_EQ(*val, "hello");
}

TEST(ItemViewTest, ByteStringType) {
  auto item = std::make_unique<cppbor::Bstr>("world");
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kByteString);
  auto val = view.GetByteString();
  ABSL_ASSERT_OK(val);
  EXPECT_EQ(*val, "world");
}

TEST(ItemViewTest, MapType) {
  auto item = std::make_unique<cppbor::Map>();
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kMap);
  auto val = view.GetMap();
  ABSL_ASSERT_OK(val);
}

TEST(ItemViewTest, ArrayType) {
  auto item = std::make_unique<cppbor::Array>();
  ItemView view(item.get());
  EXPECT_EQ(view.type(), ItemView::Type::kArray);
  auto val = view.GetArray();
  ABSL_ASSERT_OK(val);
}

TEST(ItemViewTest, IsNull) {
  auto item = std::make_unique<cppbor::Null>();
  ItemView view(item.get());
  EXPECT_TRUE(view.IsNull());
}

TEST(ItemViewTest, Failures) {
  auto item = std::make_unique<cppbor::Uint>(42);
  ItemView view(item.get());

  EXPECT_THAT(view.GetBool().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetFloat().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetDouble().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetString().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetByteString().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetMap().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_THAT(view.GetArray().status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
}

TEST(MapViewTest, GetMethods) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("bool", cppbor::Bool(true));
  map->add("int", cppbor::Uint(42));
  map->add("string", cppbor::Tstr("value"));
  map->add(42, cppbor::Uint(24));

  MapView view(map.get());

  auto bool_val = view.GetBool("bool");
  ABSL_ASSERT_OK(bool_val);
  EXPECT_TRUE(*bool_val);

  auto int_val = view.GetUint64("int");
  ABSL_ASSERT_OK(int_val);
  EXPECT_EQ(*int_val, 42);

  auto str_val = view.GetString("string");
  ABSL_ASSERT_OK(str_val);
  EXPECT_EQ(*str_val, "value");

  auto int_key_val = view.GetInt64(42);
  ABSL_ASSERT_OK(int_key_val);
  EXPECT_EQ(*int_key_val, 24);
}

TEST(MapViewTest, GetOptional) {
  auto map = std::make_unique<cppbor::Map>();
  map->add("bool", cppbor::Bool(true));

  MapView view(map.get());

  EXPECT_TRUE(view.GetOptionalBool("bool").has_value());
  EXPECT_TRUE(view.GetOptionalBool("bool").value());
  EXPECT_FALSE(view.GetOptionalBool("nonexistent").has_value());
}

TEST(MapViewTest, Failures) {
  auto map = std::make_unique<cppbor::Map>();
  MapView view(map.get());

  EXPECT_THAT(view.GetBool("nonexistent").status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
}

TEST(ArrayViewTest, GetMethods) {
  auto array = std::make_unique<cppbor::Array>();
  array->add(cppbor::Bool(true));
  array->add(cppbor::Uint(42));

  ArrayView view(array.get());

  EXPECT_EQ(view.size(), 2);
  EXPECT_FALSE(view.empty());

  auto bool_val = view.GetBool(0);
  ABSL_ASSERT_OK(bool_val);
  EXPECT_TRUE(*bool_val);

  auto int_val = view.GetUint64(1);
  ABSL_ASSERT_OK(int_val);
  EXPECT_EQ(*int_val, 42);
}

TEST(ArrayViewTest, Failures) {
  auto array = std::make_unique<cppbor::Array>();
  ArrayView view(array.get());

  EXPECT_THAT(view.GetBool(0).status().code(),
              Eq(absl::StatusCode::kInvalidArgument));
  EXPECT_EQ(view.value_type(0), ItemView::Type::kUnknown);
  EXPECT_EQ(view.value_type(1), ItemView::Type::kUnknown);

  array->add(cppbor::Uint(42));
  EXPECT_EQ(view.value_type(0), ItemView::Type::kUint64);
  EXPECT_EQ(view.value_type(1), ItemView::Type::kUnknown);
}

}  // namespace
}  // namespace cbor
