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

#include <memory>
#include <optional>
#include <string>

#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "constants/status_codes.h"
#include "crypto/algorithms.h"
#include "crypto/hash.h"
#include "jumbf/uri.h"
#include "jumbf/utils.h"
#include "proto/hashed_uri.pb.h"
#include "validator/tracker.h"

namespace credentio {

std::optional<std::string> HashedUriValidator::Validate(
    const HashedUri& hashed_uri, absl::string_view assertion_url,
    ValidationTracker& validation_tracker) const {
  auto record_failure = [&](FailureStatusCode code,
                            absl::string_view explanation =
                                "") -> std::optional<std::string> {
    validation_tracker.RecordFailure(
        code, {.url = assertion_url, .explanation = explanation});
    return std::nullopt;
  };

  // Check the uri.
  auto path = jumbf::UriResolver::GetAbsolutePathFromUri(hashed_uri.url(),
                                                         manifest_path_);
  if (!path.ok()) {
    return record_failure(codes_.missing, path.status().message());
  }
  auto box = uri_resolver_.ResolvePath(*path);
  if (!box.ok()) {
    return record_failure(codes_.missing, box.status().message());
  }

  // Check the algorithm.
  absl::string_view alg_name =
      hashed_uri.algorithm().empty() ? alg_ : hashed_uri.algorithm();
  auto algorithm = ParseHashAlgorithm(alg_name);
  if (!algorithm.ok()) {
    return record_failure(FailureStatusCode::kAlgorithmUnsupported);
  }
  auto checker = hash_checker_factory_.Create(*algorithm);
  if (!checker.ok()) {
    return record_failure(FailureStatusCode::kAlgorithmUnsupported);
  }

  // Check the hash.
  auto box_bytes = jumbf::StripBoxHeaders((*box)->raw_bytes);
  if (!box_bytes.ok()) {
    return record_failure(codes_.mismatch);
  }
  (*checker)->Update(*box_bytes);
  if (!(*checker)->Check(hashed_uri.hash())) {
    return record_failure(codes_.mismatch);
  }

  return *path;
}

}  // namespace credentio
