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

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "cbor/cbor.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "testing/cbor_utils.h"

namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::cbor::FromJson;
using ::testing::Eq;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsFalse;
using ::testing::IsTrue;

#ifndef ASSERT_OK_AND_ASSIGN
#define ASSERT_OK_AND_ASSIGN_CONCAT2(x, y) x##y
#define ASSERT_OK_AND_ASSIGN_CONCAT(x, y) ASSERT_OK_AND_ASSIGN_CONCAT2(x, y)

#define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
  ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, __COUNTER__)

#define ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, id)             \
  auto ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id) = (rexpr); \
  ASSERT_THAT(ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id),    \
              ::absl_testing::IsOk());                        \
  lhs = std::move(*ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id))
#endif

TEST(ParseTest, Okay) {
  auto cbor = FromJson(R"json({
      "str": "Google",
      "uint": 0,
      "int": -1,
      "nest_map": {"a": 1},
      "empty_map": {},
      "uint_array": [1, 2, 3],
      "int_array": [-1, -2, -3],
      "str_array": ["a", "b", "c"],
      "array_of_map": [{"a": 1}, {"a": 2}],
      "array_of_array": [[1, 2], [3, 4]],
      "empty_array": [],
      "null_array": [null]
      })json");
  auto value1 = cbor::Parse(cbor);
  ASSERT_TRUE(value1.ok());
  auto result = std::move(value1).value();
  auto value2 = result->AsMap();
  ASSERT_TRUE(value2.ok());
  auto map = std::move(value2).value();

  EXPECT_THAT(map.GetString("str"), IsOkAndHolds("Google"));
  EXPECT_THAT(map.GetUint64("uint"), IsOkAndHolds(0));
  EXPECT_THAT(map.GetInt64("int"), IsOkAndHolds(-1));

  auto value3 = map.GetMap("nest_map");
  ASSERT_TRUE(value3.ok());
  auto nest_map = std::move(value3).value();
  EXPECT_THAT(nest_map.GetInt64("a"), IsOkAndHolds(1));

  auto value4 = map.GetMap("empty_map");
  ASSERT_TRUE(value4.ok());
  auto empty_map = std::move(value4).value();
  EXPECT_THAT(empty_map.GetInt64("a"),
              StatusIs(absl::StatusCode::kInvalidArgument));

  auto value5 = map.GetArray("uint_array");
  ASSERT_TRUE(value5.ok());
  auto uint_array = std::move(value5).value();
  EXPECT_THAT(uint_array.size(), Eq(3));
  for (int i = 0; i < 3; ++i) {
    EXPECT_THAT(uint_array.GetUint64(i), IsOkAndHolds(i + 1));
  }

  auto value6 = map.GetArray("int_array");
  ASSERT_TRUE(value6.ok());
  auto int_array = std::move(value6).value();
  EXPECT_THAT(int_array.size(), Eq(3));
  for (int i = 0; i < 3; ++i) {
    EXPECT_THAT(int_array.GetInt64(i), IsOkAndHolds(-1 - i));
  }

  auto value7 = map.GetArray("str_array");
  ASSERT_TRUE(value7.ok());
  auto str_array = std::move(value7).value();
  EXPECT_THAT(str_array.size(), Eq(3));
  EXPECT_THAT(str_array.empty(), IsFalse());
  for (int i = 0; i < 3; ++i) {
    EXPECT_THAT(str_array.GetString(i), IsOkAndHolds(std::string(1, 'a' + i)));
  }

  auto value8 = map.GetArray("array_of_map");
  ASSERT_TRUE(value8.ok());
  auto array_of_map = std::move(value8).value();
  EXPECT_THAT(array_of_map.size(), Eq(2));
  auto value9 = array_of_map.GetMap(0);
  ASSERT_TRUE(value9.ok());
  auto array_of_map_0 = std::move(value9).value();
  EXPECT_THAT(array_of_map_0.GetInt64("a"), IsOkAndHolds(1));
  auto value10 = array_of_map.GetMap(1);
  ASSERT_TRUE(value10.ok());
  auto array_of_map_1 = std::move(value10).value();
  EXPECT_THAT(array_of_map_1.GetInt64("a"), IsOkAndHolds(2));

  auto value11 = map.GetArray("array_of_array");
  ASSERT_TRUE(value11.ok());
  auto array_of_array = std::move(value11).value();
  EXPECT_THAT(array_of_array.size(), Eq(2));
  auto value12 = array_of_array.GetArray(0);
  ASSERT_TRUE(value12.ok());
  auto array_of_array_0 = std::move(value12).value();
  EXPECT_THAT(array_of_array_0.size(), Eq(2));
  EXPECT_THAT(array_of_array_0.GetUint64(0), IsOkAndHolds(1));
  EXPECT_THAT(array_of_array_0.GetUint64(1), IsOkAndHolds(2));
  auto value13 = array_of_array.GetArray(1);
  ASSERT_TRUE(value13.ok());
  auto array_of_array_1 = std::move(value13).value();
  EXPECT_THAT(array_of_array_1.size(), Eq(2));
  EXPECT_THAT(array_of_array_1.GetUint64(0), IsOkAndHolds(3));
  EXPECT_THAT(array_of_array_1.GetUint64(1), IsOkAndHolds(4));

  auto value14 = map.GetArray("empty_array");
  ASSERT_TRUE(value14.ok());
  auto empty_array = std::move(value14).value();
  EXPECT_THAT(empty_array.size(), Eq(0));
  EXPECT_THAT(empty_array.empty(), IsTrue());

  auto value15 = map.GetArray("null_array");
  ASSERT_TRUE(value15.ok());
  auto null_array = std::move(value15).value();
  EXPECT_THAT(null_array.size(), Eq(1));
  EXPECT_THAT(null_array.IsNull(0), IsOkAndHolds(IsTrue()));
  EXPECT_THAT(str_array.IsNull(0), IsOkAndHolds(IsFalse()));
}

TEST(ParseTest, SemanticTag) {
  cppbor::Map orig_map;
  orig_map.add("when",
               cppbor::SemanticTag(0, cppbor::Tstr("2026-05-19T00:00:00Z")));
  orig_map.add("epoch", cppbor::SemanticTag(1, cppbor::Uint(1684454400)));
  auto bytes = orig_map.encode();
  absl::string_view bytes_view(reinterpret_cast<const char*>(bytes.data()),
                               bytes.size());
  auto value = cbor::Parse(bytes_view);
  ASSERT_TRUE(value.ok());
  auto result = std::move(value).value();
  auto map_or = result->AsMap();
  ASSERT_TRUE(map_or.ok());
  auto map = std::move(map_or).value();
  EXPECT_THAT(map.GetString("when"), IsOkAndHolds("2026-05-19T00:00:00Z"));
  EXPECT_THAT(map.GetUint64("epoch"), IsOkAndHolds(1684454400));
}

TEST(ParseTest, OptionalString) {
  auto cbor = FromJson(R"json({"str": "Google", "int": 0})json");
  auto value16 = cbor::Parse(cbor);
  ASSERT_TRUE(value16.ok());
  auto result = std::move(value16).value();
  auto value17 = result->AsMap();
  ASSERT_TRUE(value17.ok());
  auto map = std::move(value17).value();
  EXPECT_THAT(map.GetOptionalString("str"), Eq("Google"));
  EXPECT_THAT(map.GetOptionalString("not_found"), Eq(std::nullopt));
  EXPECT_THAT(map.GetOptionalString("int"), Eq(std::nullopt));
}

TEST(ParseTest, OptionalMap) {
  auto cbor = FromJson(
      R"json({"not_map": "Google", "map":  {"a": 1}, "empty_map": {}})json");
  auto value18 = cbor::Parse(cbor);
  ASSERT_TRUE(value18.ok());
  auto result = std::move(value18).value();
  auto value19 = result->AsMap();
  ASSERT_TRUE(value19.ok());
  auto map = std::move(value19).value();
  EXPECT_THAT(map.GetOptionalMap("not_map"), Eq(std::nullopt));
  EXPECT_THAT(map.GetOptionalMap("not_found"), Eq(std::nullopt));
  EXPECT_TRUE(map.GetOptionalMap("map").has_value());
  EXPECT_TRUE(map.GetOptionalMap("empty_map").has_value());
}

TEST(ParseTest, OptionalArray) {
  auto cbor = FromJson(
      R"json({"not_array": "Google", "array": [1, 2], "empty_array": []})json");
  auto value20 = cbor::Parse(cbor);
  ASSERT_TRUE(value20.ok());
  auto result = std::move(value20).value();
  auto value21 = result->AsMap();
  ASSERT_TRUE(value21.ok());
  auto map = std::move(value21).value();
  EXPECT_THAT(map.GetOptionalArray("not_array"), Eq(std::nullopt));
  EXPECT_THAT(map.GetOptionalArray("not_found"), Eq(std::nullopt));
  EXPECT_TRUE(map.GetOptionalArray("array").has_value());
  EXPECT_TRUE(map.GetOptionalArray("empty_array").has_value());
}

TEST(ParseTest, OptionalUint64) {
  auto cbor = FromJson(R"json({"not_uint": "Google", "uint": 1})json");
  auto value22 = cbor::Parse(cbor);
  ASSERT_TRUE(value22.ok());
  auto result = std::move(value22).value();
  auto value23 = result->AsMap();
  ASSERT_TRUE(value23.ok());
  auto map = std::move(value23).value();
  EXPECT_THAT(map.GetOptionalUint64("not_uint"), Eq(std::nullopt));
  EXPECT_THAT(map.GetOptionalUint64("not_found"), Eq(std::nullopt));
  EXPECT_THAT(map.GetOptionalUint64("uint").value(), Eq(1));
}

TEST(ParseTest, UintMapKeys) {
  // FromJson doesn't support creating integer-keyed maps -- would need
  // special support like the "b64'blah" bytestring hack because JSON doesn't
  // support integer map keys. So we'll create the map directly using cppbor.
  cppbor::Map orig_map;
  orig_map.add(cppbor::Uint(0), cppbor::Bstr("zero"));
  orig_map.add(cppbor::Uint(3), cppbor::Nint(-333));
  orig_map.add(cppbor::Uint(10),
               cppbor::Array(cppbor::Tstr("a"), cppbor::Nint(-12)));
  auto bytes = orig_map.encode();
  absl::string_view bytes_view(reinterpret_cast<char*>(bytes.data()),
                               bytes.size());
  auto value24 = cbor::Parse(bytes_view);
  ASSERT_TRUE(value24.ok());
  auto result = std::move(value24).value();
  auto value25 = result->AsMap();
  ASSERT_TRUE(value25.ok());
  auto map = std::move(value25).value();
  EXPECT_THAT(map.GetByteString(0), IsOkAndHolds("zero"));
  EXPECT_THAT(map.GetInt64(3), IsOkAndHolds(-333));
  auto value26 = map.GetArray(10);
  ASSERT_TRUE(value26.ok());
  auto arr = std::move(value26).value();
  EXPECT_THAT(arr.size(), Eq(2));
  EXPECT_THAT(arr.GetString(0), IsOkAndHolds("a"));
  EXPECT_THAT(arr.GetInt64(1), IsOkAndHolds(-12));
}

TEST(ParseTest, ErrorResultNotAMap) {
  auto cbor = FromJson(R"json([1, 2, 3])json");
  auto value27 = cbor::Parse(cbor);
  ASSERT_TRUE(value27.ok());
  auto result = std::move(value27).value();
  EXPECT_THAT(result->AsMap(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR parsed result is not a map")));
}

TEST(ParseTest, ErrorResultNotAnArray) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  auto value28 = cbor::Parse(cbor);
  ASSERT_TRUE(value28.ok());
  auto result = std::move(value28).value();
  EXPECT_THAT(result->AsArray(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR parsed result is not an array")));
}

TEST(ParseTest, ErrorMapGetStringNotAString) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  auto value29 = cbor::Parse(cbor);
  ASSERT_TRUE(value29.ok());
  auto result = std::move(value29).value();
  auto value30 = result->AsMap();
  ASSERT_TRUE(value30.ok());
  auto map = std::move(value30).value();
  EXPECT_THAT(map.GetString("schema"),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR item is not a string")));
}

TEST(ParseTest, ErrorMapGetInt64NotAnInt) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  auto value31 = cbor::Parse(cbor);
  ASSERT_TRUE(value31.ok());
  auto result = std::move(value31).value();
  auto value32 = result->AsMap();
  ASSERT_TRUE(value32.ok());
  auto map = std::move(value32).value();
  EXPECT_THAT(map.GetInt64("vendor"),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR item is not an int")));
}

TEST(ParseTest, ErrorMapGetUint64NotAUint) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  auto value33 = cbor::Parse(cbor);
  ASSERT_TRUE(value33.ok());
  auto result = std::move(value33).value();
  auto value34 = result->AsMap();
  ASSERT_TRUE(value34.ok());
  auto map = std::move(value34).value();
  EXPECT_THAT(map.GetUint64("vendor"),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR item is not an uint")));
}

TEST(ParseTest, ErrorNotAUintInArray) {
  auto cbor = FromJson(R"json(["vendor", "Google"])json");
  auto value35 = cbor::Parse(cbor);
  ASSERT_TRUE(value35.ok());
  auto result = std::move(value35).value();
  auto value36 = result->AsArray();
  ASSERT_TRUE(value36.ok());
  auto array = std::move(value36).value();
  EXPECT_THAT(array.GetUint64(0),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR item is not an uint")));
}

TEST(ParseTest, ErrorNotAMapInArray) {
  auto cbor = FromJson(R"json([{"vendor": "Google"}, "schema"])json");
  auto value37 = cbor::Parse(cbor);
  ASSERT_TRUE(value37.ok());
  auto result = std::move(value37).value();
  auto value38 = result->AsArray();
  ASSERT_TRUE(value38.ok());
  auto array = std::move(value38).value();
  EXPECT_THAT(array.GetMap(1), StatusIs(absl::StatusCode::kInvalidArgument,
                                        HasSubstr("CBOR item is not a map")));
}

TEST(ParseTest, ErrorKeyNotFound) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  auto value39 = cbor::Parse(cbor);
  ASSERT_TRUE(value39.ok());
  auto result = std::move(value39).value();
  auto value40 = result->AsMap();
  ASSERT_TRUE(value40.ok());
  auto map = std::move(value40).value();
  EXPECT_THAT(
      map.GetString("not_found"),
      StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Key not found")));
}

TEST(ParseTest, DuplicateKey) {
  std::string cbor;
  // This is a CBOR map {"color": "red", "color": "green"}.
  ASSERT_TRUE(absl::HexStringToBytes(
      "a265636f6c6f726372656465636f6c6f7265677265656e", &cbor));
  auto value41 = cbor::Parse(cbor);
  ASSERT_TRUE(value41.ok());
  auto result = std::move(value41).value();
  auto value42 = result->AsMap();
  ASSERT_TRUE(value42.ok());
  auto map = std::move(value42).value();
  EXPECT_THAT(map.GetString("color"), "red");
}

TEST(ParseTest, ErrorIndexOutOfRange) {
  auto cbor = FromJson(R"json([0, 1, 2])json");
  auto value43 = cbor::Parse(cbor);
  ASSERT_TRUE(value43.ok());
  auto result = std::move(value43).value();
  auto value44 = result->AsArray();
  ASSERT_TRUE(value44.ok());
  auto array = std::move(value44).value();
  EXPECT_THAT(array.GetUint64(3), StatusIs(absl::StatusCode::kInvalidArgument,
                                           HasSubstr("Index out of range")));
}

TEST(ParseTest, ErrorFailedToParse) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  EXPECT_THAT(cbor::Parse(cbor.substr(0, 10)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("CBOR parsing failed")));
}

TEST(ParseTest, TrailingBytesIgnored) {
  auto cbor = FromJson(R"json({"vendor": "Google", "schema": 0})json");
  ASSERT_OK_AND_ASSIGN(auto result, cbor::Parse(cbor + "trailing bytes"));
  ASSERT_OK_AND_ASSIGN(auto result_map, result->AsMap());
  EXPECT_THAT(result_map.GetString("vendor"), IsOkAndHolds("Google"));
  EXPECT_THAT(result_map.GetUint64("schema"), IsOkAndHolds(0));
}

void CheckMap(const cbor::MapView& map, absl::string_view str_key,
              uint32_t int_key);

void CheckArray(const cbor::ArrayView& array, absl::string_view str_key,
                uint32_t int_key) {
  if (array.empty()) {
    ASSERT_THAT(array.size(), Eq(0));
    ASSERT_THAT(array.value_type(0), Eq(cbor::ItemView::Type::kUnknown));
  } else {
    ASSERT_THAT(array.size(), Gt(0));
  }
  for (auto i = 0; i < array.size(); ++i) {
    SCOPED_TRACE(absl::StrCat(i));
    switch (array.value_type(i)) {
      case cbor::ItemView::Type::kUnknown:
        EXPECT_THAT(array.GetBool(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetFloat(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetDouble(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetString(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetByteString(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetInt64(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetUint64(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetMap(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        EXPECT_THAT(array.GetArray(i),
                    StatusIs(absl::StatusCode::kInvalidArgument));
        break;
      case cbor::ItemView::Type::kBool:
        EXPECT_THAT(array.GetBool(i), StatusIs(absl::StatusCode::kOk));
        break;
      case cbor::ItemView::Type::kFloat:
        EXPECT_THAT(array.GetFloat(i), StatusIs(absl::StatusCode::kOk));
        break;
      case cbor::ItemView::Type::kDouble:
        EXPECT_THAT(array.GetDouble(i), StatusIs(absl::StatusCode::kOk));
        break;
      case cbor::ItemView::Type::kString: {
        auto value45 = array.GetString(i);
        ASSERT_TRUE(value45.ok());
        absl::string_view str = std::move(value45).value();
        std::string force_copy(str);
        break;
      }
      case cbor::ItemView::Type::kByteString: {
        auto value46 = array.GetByteString(i);
        ASSERT_TRUE(value46.ok());
        absl::string_view str = std::move(value46).value();
        std::string force_copy(str);
        break;
      }
      case cbor::ItemView::Type::kInt64:
        EXPECT_THAT(array.GetInt64(i), StatusIs(absl::StatusCode::kOk));
        break;
      case cbor::ItemView::Type::kUint64:
        EXPECT_THAT(array.GetUint64(i), StatusIs(absl::StatusCode::kOk));
        break;
      case cbor::ItemView::Type::kMap: {
        auto value47 = array.GetMap(i);
        ASSERT_TRUE(value47.ok());
        auto child = std::move(value47).value();
        CheckMap(child, str_key, int_key);
        break;
      }
      case cbor::ItemView::Type::kArray: {
        auto value48 = array.GetArray(i);
        ASSERT_TRUE(value48.ok());
        auto child = std::move(value48).value();
        CheckArray(child, str_key, int_key);
        break;
      }
    }
  }
}

void CheckMap(const cbor::MapView& map, absl::string_view str_key,
              uint32_t int_key) {
  {
    // Bool:
    const auto status_bool = map.GetBool(str_key);
    const auto opt_bool = map.GetOptionalBool(str_key);
    ASSERT_THAT(status_bool.ok(), Eq(opt_bool.has_value()));
    if (status_bool.ok()) {
      EXPECT_THAT(*status_bool, Eq(*opt_bool));
    }
  }
  {
    // String:
    const auto status_str = map.GetString(str_key);
    const auto opt_str = map.GetOptionalString(str_key);
    ASSERT_THAT(status_str.ok(), Eq(opt_str.has_value()));
    if (status_str.ok()) {
      EXPECT_THAT(*status_str, Eq(*opt_str));
    }
  }
}

}  // namespace
