// 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_BINDINGS_VALIDATOR_H_
#define THIRD_PARTY_CREDENTIO_BINDINGS_VALIDATOR_H_

#include <cstdint>
#include <memory>
#include <optional>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/functional/function_ref.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "formats/asset_box.h"
#include "formats/byte_range.h"
#include "formats/core_registry.h"
#include "formats/format.h"
#include "formats/registry.h"
#include "proto/assertion.pb.h"
#include "proto/bmff_based_hash_assertion.pb.h"
#include "proto/boxes_hash_assertion.pb.h"
#include "proto/collection_data_hash_assertion.pb.h"
#include "proto/data_hash_assertion.pb.h"
#include "proto/multi_asset_hash_assertion.pb.h"
#include "proto/validation_result.pb.h"
#include "riegeli/bytes/reader.h"
#include "utils/status_tracker.h"
#include "utils/two_stage_status_tracker.h"

namespace credentio {

// ContentBindingValidator validates that the hard binding assertions in a
// manifest match the structure and data of the associated asset binary content.
class ContentBindingValidator {
 public:
  ContentBindingValidator() : format_registry_(CreateCoreFormatRegistry()) {}
  ~ContentBindingValidator() = default;

  // Validates the hard binding assertions in the given partial validation
  // result and returns a full validation result.
  absl::StatusOr<std::unique_ptr<ValidationResultProto>> Validate(
      riegeli::Reader& contents, const Format& format,
      std::unique_ptr<PartialValidationResultProto> partial_validation_result)
      const;

 protected:
  struct Structure {
    ByteRange asset;
    std::optional<ByteRange> manifest_store_location;
    std::vector<AssetBox> boxes;

    bool operator==(const Structure& other) const {
      return asset == other.asset &&
             manifest_store_location == other.manifest_store_location &&
             boxes == other.boxes;
    }
    bool operator!=(const Structure& other) const { return !(*this == other); }
  };

  absl::StatusOr<std::vector<ContentBindingValidator::Structure>> GetStructure(
      riegeli::Reader& contents, const Format& format) const;

 private:
  // A FunctionRef that retrieves an assertion by its absolute JUMBF URI.
  using AssertionFetcherRef =
      absl::FunctionRef<const Assertion* absl_nullable(absl::string_view uri)>;

  std::unique_ptr<FormatRegistry> format_registry_;

  absl::StatusOr<int64_t> PopulateStructureFromBoxes(
      std::vector<AssetBox> boxes,
      ContentBindingValidator::Structure& structure) const;

  absl::StatusOr<Structure> ExtractAssetStructure(riegeli::Reader& contents,
                                                  const Format* format,
                                                  int64_t end_offset) const;

  absl::Status ValidateAssertion(
      riegeli::Reader& contents, AssertionFetcherRef assertion_fetcher,
      absl::string_view assertion_uri,
      std::vector<ContentBindingValidator::Structure> asset_structure,
      bool requires_c2pa, TwoStageStatusTracker& tracker,
      bool assertion_in_ingredient_manifest, int64_t end_offset = -1) const;

  absl::Status ValidateDataHash(
      riegeli::Reader& contents, absl::string_view assertion_uri,
      const DataHashAssertion& assertion,
      std::optional<ByteRange> manifest_store_location, bool requires_c2pa,
      StatusTracker& tracker, bool assertion_in_ingredient_manifest,
      int64_t end_offset = -1) const;

  absl::Status ValidateCollectionDataHash(
      riegeli::Reader& contents, absl::string_view assertion_uri,
      const CollectionDataHashAssertion& assertion, bool requires_c2pa,
      StatusTracker& tracker) const;

  absl::Status ValidateBoxesHash(
      riegeli::Reader& contents, absl::string_view assertion_uri,
      const BoxesHashAssertion& assertion,
      std::vector<ContentBindingValidator::Structure> remaining_structure,
      bool requires_c2pa, StatusTracker& tracker,
      int64_t end_offset = -1) const;

  absl::Status ValidateBmffHash(riegeli::Reader& contents,
                                absl::string_view assertion_uri,
                                const BmffBasedHashAssertion& assertion,
                                bool requires_c2pa,
                                StatusTracker& tracker) const;

  absl::Status ValidateMultiAssetHash(
      riegeli::Reader& contents, absl::string_view assertion_uri,
      const MultiAssetHashAssertion& assertion,
      std::vector<ContentBindingValidator::Structure> asset_structure,
      bool requires_c2pa, AssertionFetcherRef assertion_fetcher,
      TwoStageStatusTracker& tracker,
      bool assertion_in_ingredient_manifest) const;
};

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_BINDINGS_VALIDATOR_H_
