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

#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "bindings/input_hasher.h"
#include "bindings/merkle.h"
#include "cbor/cbor.h"
#include "cbor/parse.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "crypto/hash.h"
#include "formats/bmff/box_header.h"
#include "proto/bmff_based_hash_assertion.cbor.h"
#include "proto/bmff_based_hash_assertion.pb.h"
#include "riegeli/bytes/reader.h"
#include "utils/riegeli.h"
#include "utils/status_tracker.h"

namespace credentio {

namespace {

std::string GetMerkleKey(int64_t unique_id, int64_t local_id) {
  return absl::StrFormat("%d-%d", unique_id, local_id);
}

absl::StatusOr<std::string> ReadPurpose(riegeli::Reader& contents) {
  std::string purpose;
  if (!ReadNullTerminatedString(contents, 20, purpose)) {
    return contents.StatusOrAnnotate(absl::DataLossError("kUnexpectedEof"));
  }
  return purpose;
}

absl::StatusOr<BmffMerkleMap> ReadBmffMerkleMap(riegeli::Reader& contents,
                                                int64_t length) {
  constexpr int64_t kMaxMerkleMapSize = 10 * 1024 * 1024;  // 10 MiB
  if (length < 0 || length > kMaxMerkleMapSize) {
    return absl::InvalidArgumentError(
        absl::StrFormat("invalid length for merkle map: %d", length));
  }
  std::string aux_box_raw;
  if (!contents.Read(length, aux_box_raw)) {
    return absl::InternalError("failed to read auxiliary merkle map");
  }

  BmffMerkleMap aux_box;
  ABSL_ASSIGN_OR_RETURN(auto aux_box_cbor, cbor::Parse(aux_box_raw));
  ABSL_ASSIGN_OR_RETURN(auto aux_box_cbor_map, aux_box_cbor->AsMap());
  ABSL_RETURN_IF_ERROR(cbor::ToProto(aux_box_cbor_map, &aux_box));
  return aux_box;
}

absl::StatusOr<std::string> ComputeLeafHash(const HasherFactory& factory,
                                            riegeli::Reader& contents,
                                            int64_t offset, int64_t length) {
  ABSL_ASSIGN_OR_RETURN(auto hasher, factory.Create());
  ABSL_ASSIGN_OR_RETURN(auto input_hasher,
                        InputHasher::Create(std::move(hasher)));
  ABSL_RETURN_IF_ERROR(input_hasher->Update(contents, offset, length));
  return input_hasher->Digest();
}

absl::StatusOr<std::string> JoinHashes(const HasherFactory& factory,
                                       absl::string_view hash1,
                                       absl::string_view hash2) {
  ABSL_ASSIGN_OR_RETURN(auto hasher, factory.Create());
  hasher->Update(hash1);
  hasher->Update(hash2);
  return hasher->Digest();
}

struct LeafData {
  std::vector<BmffBoxHeader> mdat_atoms;
  absl::flat_hash_map<std::string, std::vector<BmffMerkleMap>> auxiliary_data;
};

absl::StatusOr<LeafData> ExtractLeafData(riegeli::Reader& contents) {
  LeafData result;

  if (!contents.Seek(0) || contents.pos() != 0) {
    return absl::InternalError("failed to seek to start of file");
  }
  auto status = IterateOverBmffBoxes(
      contents,
      [&result,
       &contents](const BmffBoxHeader& header) -> absl::StatusOr<bool> {
        // Non-fragmented assets have 1 merkle tree per `mdat`
        // Fragmented assets could have merkle tree per track
        // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_general_20
        if (header.type == "mdat") {
          // Non-fragmented assets require auxiliary data after the last mdat.
          // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_non_fragmented_asset_that_can_be_validated_piecewise
          if (!result.auxiliary_data.empty()) {
            return absl::InvalidArgumentError(
                "encountered auxiliary atom before the first mdat atom");
          }
          result.mdat_atoms.push_back(header);
        }
        if (header.type == "uuid" &&
            header.user_type == credentio::kC2paBmffBoxUuid) {
          // Read next string to determine the purpose of the uuid atom.
          ABSL_ASSIGN_OR_RETURN(auto purpose, ReadPurpose(contents));

          if (purpose == "merkle") {
            uint64_t end_of_box = header.start + header.box_size;
            if (contents.pos() >= end_of_box) {
              return absl::InvalidArgumentError(
                  "box size too small for metadata headers");
            }
            uint64_t remaining_data = end_of_box - contents.pos();
            ABSL_ASSIGN_OR_RETURN(auto aux_box,
                                  ReadBmffMerkleMap(contents, remaining_data));

            result
                .auxiliary_data[GetMerkleKey(aux_box.unique_id(),
                                             aux_box.local_id())]
                .push_back(aux_box);
          }
        }
        return true;
      });
  ABSL_RETURN_IF_ERROR(status);
  return result;
}

}  // namespace

absl::Status MerkleValidator::ValidateMerkleMap(
    const BmffMerkle& merkle, const BmffBoxHeader& mdat_atom,
    std::vector<BmffMerkleMap> auxiliary_merkle_maps,
    absl::string_view fallback_algo, StatusTracker& tracker) const {
  if (merkle.has_init_hash()) {
    tracker.RecordFailure(
        FailureStatusCode::kGoogleInternalError,
        {.url = assertion_uri_,
         .explanation = "fragmented merkle validations are not supported yet"});
    return absl::UnimplementedError(
        "fragmented merkle validations are not supported yet");
  }

  // Derive the full row sizes and number of rows away and validates the counts.
  absl::StatusOr<DerivedTreeData> derived_data = DeriveMerkleTreeData(
      merkle.count(), merkle.hashes_size(), auxiliary_merkle_maps.size());
  if (!derived_data.ok()) {
    tracker.RecordFailure(FailureStatusCode::kAssertionBmffHashMalformed,
                          {.url = assertion_uri_,
                           .explanation = derived_data.status().message()});
    return derived_data.status();
  }

  uint64_t mdat_offset_adjustment = 0;
  for (const auto& exclusion : assertion_.exclusions()) {
    if (exclusion.xpath() == "/mdat" && !exclusion.subsets().empty()) {
      mdat_offset_adjustment = exclusion.subsets(0).offset();
      break;
    }
  }

  uint64_t header_or_adjustment_size =
      std::max<uint64_t>(mdat_atom.header_size, mdat_offset_adjustment);

  if (mdat_atom.box_size < header_or_adjustment_size) {
    tracker.RecordFailure(
        FailureStatusCode::kAssertionBmffHashMalformed,
        {.url = assertion_uri_,
         .explanation = "mdat atom box_size is smaller than header_size or "
                        "exclusion adjustment"});
    return absl::InvalidArgumentError(
        "mdat atom box_size is smaller than header_size or exclusion "
        "adjustment");
  }

  // Calculate and validate the lengths of each leaf using net payload size.
  uint64_t net_mdat_payload_size =
      mdat_atom.box_size - header_or_adjustment_size;
  absl::StatusOr<std::vector<int64_t>> leaf_sizes =
      DeriveMerkleBlockSizes(merkle, net_mdat_payload_size);
  if (!leaf_sizes.ok()) {
    tracker.RecordFailure(
        FailureStatusCode::kAssertionBmffHashMalformed,
        {.url = assertion_uri_, .explanation = leaf_sizes.status().message()});
    return leaf_sizes.status();
  }

  // Based on the above calculations, we ensure the assertion is not malformed,
  // now compute and compare the leaf hashes.
  uint64_t offset = mdat_atom.start + header_or_adjustment_size;
  for (int64_t i = 0; i < merkle.count(); ++i) {
    absl::string_view algo = merkle.has_alg() ? merkle.alg() : fallback_algo;
    absl::StatusOr<std::unique_ptr<HasherFactory>> factory =
        factory_provider_->Create(algo);
    if (!factory.ok()) {
      tracker.RecordFailure(FailureStatusCode::kAssertionBmffHashMalformed,
                            {.url = assertion_uri_,
                             .explanation = absl::StrFormat(
                                 "unsupported hash algorithm: %s", algo)});
      return absl::InvalidArgumentError(
          absl::StrFormat("unsupported hash algorithm: %s", algo));
    }

    absl::StatusOr<std::string> leaf_hash =
        ComputeLeafHash(**factory, contents_, offset, leaf_sizes.value()[i]);
    offset += leaf_sizes.value()[i];
    if (!leaf_hash.ok()) {
      tracker.RecordFailure(
          FailureStatusCode::kAssertionBmffHashMalformed,
          {.url = assertion_uri_, .explanation = leaf_hash.status().message()});
      return leaf_hash.status();
    }

    std::string computed_hash = std::move(leaf_hash.value());

    uint64_t running_row_index = i;
    if (!auxiliary_merkle_maps.empty()) {
      BmffMerkleMap auxiliary = auxiliary_merkle_maps[i];
      int64_t location = auxiliary.location();
      uint64_t lvl = 0;
      int64_t trailing_boundary = (merkle.count() - 1) & ~1LL;
      for (const auto& hash : auxiliary.hashes()) {
        bool sibling_on_left = (running_row_index % 2 == 1) ||
                               (location >= trailing_boundary && lvl >= 1);
        if (sibling_on_left) {
          ABSL_ASSIGN_OR_RETURN(computed_hash,
                                JoinHashes(**factory, hash, computed_hash));
        } else {
          ABSL_ASSIGN_OR_RETURN(computed_hash,
                                JoinHashes(**factory, computed_hash, hash));
        }
        running_row_index >>= 1;
        ++lvl;
      }
    }

    uint64_t hashes_index = i >> derived_data->delta_rows;
    if (merkle.hashes(hashes_index) != computed_hash) {
      tracker.RecordFailure(FailureStatusCode::kAssertionBmffHashMismatch,
                            {.url = assertion_uri_,
                             .explanation = absl::StrFormat(
                                 "merkle map hash mismatch on leaf: %d", i)});
      return absl::InternalError("merkle map hash mismatch");
    }
  }
  return absl::OkStatus();
}

absl::Status MerkleValidator::Validate(StatusTracker& tracker) const {
  absl::StatusOr<LeafData> atoms = ExtractLeafData(contents_);
  if (!atoms.ok()) {
    tracker.RecordFailure(
        FailureStatusCode::kGoogleInternalError,
        {.url = assertion_uri_, .explanation = atoms.status().message()});
    return absl::InternalError("failed to extract leaf data");
  }
  if (atoms->mdat_atoms.size() != assertion_.merkles_size()) {
    // This should only apply to non-fragmented assets.
    tracker.RecordFailure(
        FailureStatusCode::kAssertionBmffHashMalformed,
        {.url = assertion_uri_,
         .explanation =
             "number of mdat atoms does not match the number of merkle maps"});
    return absl::InternalError(
        "number of mdat atoms does not match the number of merkle maps");
  }

  for (int64_t i = 0; i < atoms->mdat_atoms.size(); ++i) {
    BmffMerkle merkle = assertion_.merkles(i);
    const auto& aux_maps = atoms->auxiliary_data[GetMerkleKey(
        merkle.unique_id(), merkle.local_id())];
    ABSL_RETURN_IF_ERROR(ValidateMerkleMap(
        merkle, atoms->mdat_atoms[i], aux_maps, assertion_.alg(), tracker));
  }
  return absl::OkStatus();
}

}  // namespace credentio
