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

#include <memory>
#include <utility>

#include "absl/base/nullability.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "bindings/binding_hasher.h"
#include "bindings/bmff_binding_hasher.h"
#include "bindings/bmff_exclusion_checker.h"
#include "bindings/merkle_validator.h"
#include "constants/status_codes.h"
#include "formats/asset_byte_info.h"
#include "proto/bmff_based_hash_assertion.pb.h"
#include "proto/manifest.pb.h"
#include "proto/multi_asset_hash_assertion.pb.h"
#include "proto/validation_result.pb.h"
#include "riegeli/bytes/reader.h"
#include "utils/dual_status_tracker.h"
#include "utils/status_tracker.h"
#include "validator/result.h"
#include "validator/validation_result_internal.h"

namespace credentio {

namespace {
class BmffHashBindingHasherTracker : public BindingHasherTracker {
 public:
  explicit BmffHashBindingHasherTracker(StatusTracker* tracker,
                                        absl::string_view hard_binding_uri)
      : tracker_(*ABSL_DIE_IF_NULL(tracker)),
        hard_binding_uri_(hard_binding_uri) {}
  void RecordMismatch() override {
    tracker_.RecordFailure(FailureStatusCode::kAssertionBmffHashMismatch,
                           {.url = hard_binding_uri_});
  }
  void RecordMalformed() override {
    tracker_.RecordFailure(FailureStatusCode::kAssertionBmffHashMalformed,
                           {.url = hard_binding_uri_});
  }
  void RecordAlgorithmUnsupported() override {
    tracker_.RecordFailure(FailureStatusCode::kAlgorithmUnsupported,
                           {.url = hard_binding_uri_});
  }
  void RecordGeneralError(absl::Status error) override {
    tracker_.RecordFailure(
        FailureStatusCode::kGeneralError,
        {.url = hard_binding_uri_, .explanation = error.message()});
  }

 private:
  StatusTracker& tracker_;
  absl::string_view hard_binding_uri_;
};
}  // namespace

absl::StatusOr<std::unique_ptr<ValidationResultProto>>
BmffHashHardBindingValidator::Validate(
    riegeli::Reader& contents, const AssetByteInfo& asset_byte_info,
    std::unique_ptr<PartialValidationResultProto> partial_validation_result)
    const {
  const Assertion* absl_nullable assertion =
      GetAssertion(partial_validation_result.get(),
                   partial_validation_result->hard_binding_uri());
  if (assertion == nullptr) {
    return absl::InvalidArgumentError(absl::StrCat(
        "missing assertion: ", partial_validation_result->hard_binding_uri()));
  }
  if (!assertion->has_bmff_based_hash()) {
    return absl::InvalidArgumentError(
        absl::StrCat("assertion is not a bmff hash assertion: ",
                     partial_validation_result->hard_binding_uri()));
  }

  ABSL_ASSIGN_OR_RETURN(auto tracker,
                        DualStatusTracker::FromPartialValidationResult(
                            partial_validation_result.get()));

  Validate(contents, assertion->bmff_based_hash(),
           partial_validation_result->hard_binding_uri(), *tracker);

  return MakeFullValidationResult(std::move(partial_validation_result));
}

void BmffHashHardBindingValidator::Validate(
    riegeli::Reader& contents, const BmffBasedHashAssertion& assertion,
    absl::string_view hard_binding_uri, StatusTracker& tracker) const {
  if (!contents.Seek(0) || contents.pos() != 0) {
    tracker.RecordFailure(FailureStatusCode::kGoogleInternalError,
                          {.url = hard_binding_uri});
    return;
  }

  if (HasAdditionalExclusions(assertion)) {
    tracker.RecordInformational(
        InformationalStatusCode::kAssertionBmffHashAdditionalExclusionsPresent,
        {.url = hard_binding_uri});
  }

  BmffHashBindingHasherTracker hasher_tracker(&tracker, hard_binding_uri);
  BmffBindingHasher hasher(&assertion, &hasher_tracker);
  auto digest = hasher.Digest(contents);
  if (digest.value_or("") != assertion.hash()) {
    tracker.RecordFailure(FailureStatusCode::kAssertionBmffHashMismatch,
                          {.url = hard_binding_uri});
    return;
  }

  if (assertion.merkles_size() > 0) {
    MerkleValidator merkle_validator(contents, assertion, hard_binding_uri);

    if (!merkle_validator.Validate(tracker).ok()) {
      // Failure Codes were already recorded by ValidateMerkleMaps.
      return;
    }
  }

  tracker.RecordSuccess(SuccessStatusCode::kAssertionBmffHashMatch,
                        {.url = hard_binding_uri});
}

}  // namespace credentio
