// 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.
//

#ifndef THIRD_PARTY_CREDENTIO_CBOR_CBOR_H_
#define THIRD_PARTY_CREDENTIO_CBOR_CBOR_H_

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

#include "absl/base/attributes.h"
#include "absl/base/nullability.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "cppbor/cppbor.h"

namespace cbor {

class MapView;
class ArrayView;

class ItemView {
 public:
  enum class Type {
    kUnknown,
    kBool,
    kFloat,
    kDouble,
    kString,
    kByteString,
    kInt64,
    kUint64,
    kMap,
    kArray,
  };
  explicit ItemView(
      const cppbor::Item* absl_nonnull item ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : item_(ABSL_DIE_IF_NULL(item)) {}
  Type type() const;
  absl::StatusOr<bool> GetBool() const;
  absl::StatusOr<float> GetFloat() const;
  absl::StatusOr<double> GetDouble() const;
  absl::StatusOr<int64_t> GetInt64() const;
  absl::StatusOr<uint64_t> GetUint64() const;
  absl::StatusOr<absl::string_view> GetString() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<absl::string_view> GetByteString() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<MapView> GetMap() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<ArrayView> GetArray() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  // Gets the full encoded representation of this item.
  std::string ToString() const;
  bool IsNull() const;

 private:
  const cppbor::Item* absl_nonnull item_;
};

class MapView {
 public:
  explicit MapView(
      const cppbor::Map* absl_nonnull map ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : map_(ABSL_DIE_IF_NULL(map)) {}
  absl::StatusOr<bool> GetBool(absl::string_view key) const;
  std::optional<bool> GetOptionalBool(absl::string_view key) const;
  absl::StatusOr<float> GetFloat(absl::string_view key) const;
  std::optional<float> GetOptionalFloat(absl::string_view key) const;
  absl::StatusOr<double> GetDouble(absl::string_view key) const;
  std::optional<double> GetOptionalDouble(absl::string_view key) const;
  absl::StatusOr<absl::string_view> GetString(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  // Returns std::nullopt if the key is not found or the value is not a string.
  std::optional<absl::string_view> GetOptionalString(
      absl::string_view key) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<absl::string_view> GetByteString(uint32_t key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<absl::string_view> GetByteString(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::optional<absl::string_view> GetOptionalByteString(
      absl::string_view key) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<int64_t> GetInt64(absl::string_view key) const;
  absl::StatusOr<int64_t> GetInt64(uint32_t key) const;
  std::optional<int64_t> GetOptionalInt64(absl::string_view key) const;
  absl::StatusOr<uint64_t> GetUint64(absl::string_view key) const;
  std::optional<int64_t> GetOptionalUint64(absl::string_view key) const;
  absl::StatusOr<MapView> GetMap(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::optional<MapView> GetOptionalMap(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<ArrayView> GetArray(uint32_t key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<ArrayView> GetArray(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::optional<ArrayView> GetOptionalArray(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  // Gets the full encoded representation of this map.
  std::string ToString() const { return map_->toString(); }

 private:
  absl::StatusOr<ItemView> Get(uint32_t key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<ItemView> Get(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::optional<ItemView> GetOptional(absl::string_view key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  const cppbor::Map* absl_nonnull map_;
};

class ArrayView {
 public:
  explicit ArrayView(
      const cppbor::Array* absl_nonnull array ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : array_(ABSL_DIE_IF_NULL(array)) {}
  uint32_t size() const;
  bool empty() const { return size() == 0; }
  ItemView::Type value_type(uint32_t index) const;
  absl::StatusOr<bool> GetBool(uint32_t index) const;
  absl::StatusOr<float> GetFloat(uint32_t index) const;
  absl::StatusOr<double> GetDouble(uint32_t index) const;
  absl::StatusOr<absl::string_view> GetString(uint32_t index) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<absl::string_view> GetByteString(uint32_t index) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<int64_t> GetInt64(uint32_t index) const;
  absl::StatusOr<uint64_t> GetUint64(uint32_t index) const;
  absl::StatusOr<MapView> GetMap(uint32_t index) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<ArrayView> GetArray(uint32_t index) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  absl::StatusOr<bool> IsNull(uint32_t index) const;
  absl::StatusOr<ItemView> Get(uint32_t index) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
  // Gets the full encoded representation of this array.
  std::string ToString() const { return array_->toString(); }

 private:
  const cppbor::Array* absl_nonnull array_;
};

class ParseResult {
 public:
  explicit ParseResult(std::unique_ptr<cppbor::Item> item)
      : item_(std::move(item)) {}
  absl::StatusOr<ArrayView> AsArray() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!item_->asArray()) {
      return absl::InvalidArgumentError("CBOR parsed result is not an array");
    }
    return ArrayView(item_->asArray());
  }
  absl::StatusOr<MapView> AsMap() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!item_->asMap()) {
      return absl::InvalidArgumentError("CBOR parsed result is not a map");
    }
    return MapView(item_->asMap());
  }
  // Gets the full encoded representation of this item.
  std::string ToString() const { return item_->toString(); }

 private:
  std::unique_ptr<cppbor::Item> item_;
};

}  // namespace cbor

#endif  // THIRD_PARTY_CREDENTIO_CBOR_CBOR_H_
