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

#include <cstdint>
#include <utility>

#include "cbor/cbor.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "nlohmann/json.hpp"

namespace credentio {
namespace {

using Json = ::nlohmann::json;
using ::testing::ElementsAre;

TEST(UtilsTest, RecordStringPresent) {
  cppbor::Map map;
  map.add("name", "John");
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordString(map_view, "name", true, json));
  EXPECT_EQ(json["name"], "John");
}

TEST(UtilsTest, RecordStringMissingRequired) {
  cppbor::Map map;
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_FALSE(RecordString(map_view, "name", true, json));
  EXPECT_THAT(json["_missing"], ElementsAre("name"));
}

TEST(UtilsTest, RecordStringMissingNotRequired) {
  cppbor::Map map;
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_FALSE(RecordString(map_view, "name", false, json));
  EXPECT_FALSE(json.contains("name"));
  EXPECT_FALSE(json.contains("_missing"));
}

TEST(UtilsTest, RecordByteStringPresent) {
  cppbor::Map map;
  map.add("hash", cppbor::Bstr("data"));
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordByteString(map_view, "hash", true, json));
  EXPECT_EQ(json["hash"], "b64'ZGF0YQ=='");
}

TEST(UtilsTest, RecordByteStringUint32KeyPresent) {
  cppbor::Map map;
  map.add(1, cppbor::Bstr("data"));
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordByteString(map_view, 1, true, json));
  EXPECT_EQ(json["1"], "b64'ZGF0YQ=='");
}

TEST(UtilsTest, RecordUint64Present) {
  cppbor::Map map;
  map.add("size", 100);
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordUint64(map_view, "size", true, json));
  EXPECT_EQ(json["size"], 100);
}

TEST(UtilsTest, RecordUint64MissingRequired) {
  cppbor::Map map;
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_FALSE(RecordUint64(map_view, "size", true, json));
  EXPECT_THAT(json["_missing"], ElementsAre("size"));
}

TEST(UtilsTest, RecordUint64MissingNotRequired) {
  cppbor::Map map;
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_FALSE(RecordUint64(map_view, "size", false, json));
  EXPECT_FALSE(json.contains("size"));
  EXPECT_FALSE(json.contains("_missing"));
}

TEST(UtilsTest, RecordInt64Present) {
  cppbor::Map map;
  map.add("val", -100);
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordInt64(map_view, "val", true, json));
  EXPECT_EQ(json["val"], -100);
}

TEST(UtilsTest, RecordBoolPresent) {
  cppbor::Map map;
  map.add("flag", true);
  cbor::MapView map_view(&map);
  Json json = Json::object();

  EXPECT_TRUE(RecordBool(map_view, "flag", true, json));
  EXPECT_TRUE(json["flag"]);
}

TEST(UtilsTest, RecordArrayPresent) {
  cppbor::Map map;
  cppbor::Array array;
  array.add("a");
  array.add("b");
  map.add("list", std::move(array));
  cbor::MapView map_view(&map);
  Json json = Json::object();

  auto processor = [](uint32_t index, const cbor::ItemView& item) {
    if (auto val = item.GetString(); val.ok()) {
      return Json(*val);
    }
    return Json({{"_error", item.GetString().status().message()}});
  };

  EXPECT_TRUE(RecordArray(map_view, "list", true, processor, json));
  EXPECT_THAT(json["list"], ElementsAre("a", "b"));
}

TEST(UtilsTest, RecordArrayMissingRequired) {
  cppbor::Map map;
  cbor::MapView map_view(&map);
  Json json = Json::object();

  auto processor = [](uint32_t index, const cbor::ItemView& item) {
    if (auto val = item.GetString(); val.ok()) {
      return Json(*val);
    }
    return Json({{"_error", item.GetString().status().message()}});
  };

  EXPECT_FALSE(RecordArray(map_view, "list", true, processor, json));
  EXPECT_TRUE(json["list"].is_array());
  EXPECT_TRUE(json["list"].empty());
}

TEST(UtilsTest, RecordArrayOfMapsPresent) {
  cppbor::Map map;
  cppbor::Array array;
  cppbor::Map item1;
  item1.add("k1", "v1");
  cppbor::Map item2;
  item2.add("k2", "v2");
  array.add(std::move(item1));
  array.add(std::move(item2));
  map.add("list", std::move(array));
  cbor::MapView map_view(&map);
  Json json = Json::object();

  auto processor = [](const cbor::MapView& m) {
    Json j = Json::object();
    if (auto val = m.GetOptionalString("k1"); val.has_value()) {
      j["k1"] = *val;
    }
    if (auto val = m.GetOptionalString("k2"); val.has_value()) {
      j["k2"] = *val;
    }
    return j;
  };

  EXPECT_TRUE(RecordArrayOfMaps(map_view, "list", true, processor, json));
  EXPECT_EQ(json["list"][0]["k1"], "v1");
  EXPECT_EQ(json["list"][1]["k2"], "v2");
}

TEST(UtilsTest, RecordMapPresent) {
  cppbor::Map map;
  cppbor::Map sub_map;
  sub_map.add("sub_key", "sub_val");
  map.add("map_key", std::move(sub_map));
  cbor::MapView map_view(&map);
  Json json = Json::object();

  auto processor = [](const cbor::MapView& m) {
    Json j = Json::object();
    if (auto val = m.GetString("sub_key"); val.ok()) {
      j["sub_key"] = *val;
    }
    return j;
  };

  EXPECT_TRUE(RecordMap(map_view, "map_key", true, processor, json));
  EXPECT_EQ(json["map_key"]["sub_key"], "sub_val");
}

}  // namespace
}  // namespace credentio
