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

#include <optional>
#include <string>
#include <vector>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "cbor/cbor.h"
#include "cbor/parse.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "jumbf/box.h"
#include "proto/assertion.pb.h"
#include "proto/cose_verification_result.pb.h"
#include "proto/generator_info.cbor.h"
#include "proto/generator_info.pb.h"
#include "proto/hashed_uri.pb.h"
#include "proto/manifest.pb.h"
#include "proto/signature_info.pb.h"
#include "uuid/uuid.h"
#include "validator/tracker.h"

namespace credentio {
namespace {

using ::credentio::Uuid;
using ::jumbf::CborBox;
using ::jumbf::SuperBox;

constexpr absl::string_view kSignatureKey = "signature";
constexpr absl::string_view kInstanceIdKey = "instanceID";
constexpr absl::string_view kClaimSignatureUri = "self#jumbf=c2pa.signature";
constexpr absl::string_view kClaimSignatureUriPrefix = "self#jumbf=";
constexpr absl::string_view kClaimSignatureUriSuffix = "c2pa.signature";
constexpr absl::string_view kClaimGeneratorInfoKey = "claim_generator_info";
constexpr absl::string_view kClaimGeneratorV1Key = "claim_generator";
constexpr absl::string_view kCreatedAssertionsKey = "created_assertions";
constexpr absl::string_view kGatheredAssertionsKey = "gathered_assertions";
constexpr absl::string_view kRedactedAssertionsKey = "redacted_assertions";
constexpr absl::string_view kUrlKey = "url";
constexpr absl::string_view kHashKey = "hash";
constexpr absl::string_view kAlgKey = "alg";

absl::StatusOr<absl::string_view> ExtractCbor(const SuperBox* box) {
  // Check if the box only contains a single CBOR content type.
  if (box->contents.size() != 1) {
    return absl::InvalidArgumentError(
        "box contains zero or more than one contents");
  }
  const auto& content = box->contents[0];
  if (!content.Holds<CborBox>()) {
    return absl::InvalidArgumentError("box does not contain a CBOR content");
  }
  return content.Get<CborBox>().payload;
}

// See hashed-uri-map in
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_uri_references.
struct HashedUriInternal {
  absl::string_view url;
  absl::string_view hash;
  std::optional<absl::string_view> algorithm;

  HashedUri ToProto(std::optional<absl::string_view> default_algorithm) const {
    HashedUri hashed_uri;
    hashed_uri.set_url(url);
    hashed_uri.set_hash(hash);
    hashed_uri.set_algorithm(
        algorithm.value_or(default_algorithm.value_or("")));
    return hashed_uri;
  }
};

std::vector<HashedUriInternal> ParseHashedUriArray(
    const cbor::ArrayView& uri_array, ValidationTracker& validation_tracker) {
  std::vector<HashedUriInternal> assertions;
  for (int i = 0; i < uri_array.size(); ++i) {
    auto uri_map = uri_array.GetMap(i);
    if (!uri_map.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kHashedUriMissing,
                                       {});
      continue;
    }
    auto url = uri_map->GetString(kUrlKey);
    if (!url.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kHashedUriMissing,
                                       {});
      continue;
    }
    auto hash = uri_map->GetByteString(kHashKey);
    if (!hash.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kHashedUriMissing,
                                       {.url = *url});
      continue;
    }
    auto algorithm = uri_map->GetOptionalString(kAlgKey);
    assertions.push_back(
        HashedUriInternal{.url = *url, .hash = *hash, .algorithm = algorithm});
  }
  return assertions;
}

GeneratorInfo CreateGeneratorInfo(const cbor::MapView& cbor_map,
                                  absl::string_view claim_box_label,
                                  ValidationTracker& validation_tracker) {
  GeneratorInfo generator_info;
  auto holder = cbor_map.GetOptionalMap(kClaimGeneratorInfoKey);
  if (holder.has_value()) {
    auto info_map = *holder;
    auto status = cbor::ToProto(info_map, &generator_info);
    if (!status.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kClaimCborInvalid,
                                       {.url = claim_box_label});
    }
  } else if (auto v1_generator =
                 cbor_map.GetOptionalString(kClaimGeneratorV1Key);
             v1_generator.has_value()) {
    // The v1 `claim_generator` is formatted as a User-Agent string, but
    // that's at least arguably a "human readable string naming the claim
    // generator" as the `name` field is described.
    generator_info.set_name(*v1_generator);
  } else {
    validation_tracker.RecordFailure(
        FailureStatusCode::kClaimMalformed,
        {.url = claim_box_label,
         .explanation = "Claim is missing generator info"});
  }
  return generator_info;
}

struct CreateClaimOptions {
  const std::string label;
  const cbor::MapView& claim_map;
  const absl::Span<HashedUri> created_assertions;
  const absl::Span<HashedUri> gathered_assertions;
  const absl::Span<std::string> redacted_assertions;
  const std::optional<SignatureInfo> signature_info;
  std::optional<std::string> default_algorithm;
};

Claim CreateClaim(const CreateClaimOptions& options,
                  ValidationTracker& validation_tracker) {
  // Construct the claim proto.
  Claim claim;
  claim.set_label(options.label);
  // Add instance ID.
  std::optional<absl::string_view> instance_id =
      options.claim_map.GetOptionalString(kInstanceIdKey);
  if (instance_id.has_value()) {
    claim.set_instance_id(*instance_id);
  } else {
    validation_tracker.RecordFailure(
        FailureStatusCode::kClaimMalformed,
        {.url = options.label, .explanation = "Claim is missing instance ID"});
  }
  // Add signature info.
  if (options.signature_info.has_value()) {
    *claim.mutable_signature_info() = *options.signature_info;
  }
  // Add generator info.
  *claim.mutable_claim_generator_info() =
      CreateGeneratorInfo(options.claim_map, options.label, validation_tracker);
  // Add assertion URIs
  claim.mutable_created_assertions()->Add(options.created_assertions.begin(),
                                          options.created_assertions.end());
  claim.mutable_gathered_assertions()->Add(options.gathered_assertions.begin(),
                                           options.gathered_assertions.end());
  claim.mutable_redacted_assertions()->Add(options.redacted_assertions.begin(),
                                           options.redacted_assertions.end());
  if (options.default_algorithm.has_value()) {
    claim.set_default_algorithm(*options.default_algorithm);
  }
  return claim;
}

bool IsClaimBox(absl::string_view label, const Uuid& uuid) {
  if (label == kClaimV2Label && uuid == kClaimUuid) {
    return true;
  }
  if (label == kClaimV1Label && uuid == kClaimUuid) {
    return true;
  }
  return false;
}

bool IsLegacyClaimBox(absl::string_view label, const Uuid& uuid) {
  return label == kClaimV1Label && uuid == kClaimUuid;
}

// Checks if the signature URI is a self#jumbf location in the current manifest
// that is being processed (provided in the `manifest` parameter).
bool IsValidSignatureUri(absl::string_view uri,
                         const jumbf::SuperBox& manifest) {
  // Check if the signature URI is a relative URI first for efficiency.
  if (uri == kClaimSignatureUri) {
    return true;
  }
  return manifest.description.label.has_value() &&
         uri == absl::StrCat(kClaimSignatureUriPrefix, "/c2pa/",
                             *manifest.description.label, "/",
                             kClaimSignatureUriSuffix);
}

}  // namespace

std::optional<Claim> ClaimValidatorImpl::Validate(
    const jumbf::SuperBox& manifest,
    ValidationTracker& validation_tracker) const {
  std::optional<const jumbf::SuperBox*> claim_box;
  std::string claim_box_label = "";
  std::optional<const jumbf::SuperBox*> claim_signature_box;

  // Parse manifest boxes to find the claim and claim signature boxes.
  for (const auto& box : manifest.contents) {
    if (box.Holds<SuperBox>()) {
      const auto& description = box.Get<SuperBox>().description;
      absl::string_view label = description.label.value_or("");
      Uuid uid = description.type_uuid;
      if (IsLegacyClaimBox(label, uid)) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kGoogleUnsupportedSpecVersion,
            {.url = label, .explanation = "Unsupported claim version"});
        return std::nullopt;
      }
      if (IsClaimBox(label, uid)) {
        if (claim_box.has_value()) {
          validation_tracker.RecordFailure(FailureStatusCode::kClaimMultiple,
                                           {.url = label});
        }
        if (box.Holds<SuperBox>()) {
          claim_box = &box.Get<SuperBox>();
          claim_box_label = label;
        }
      } else if (label == kClaimSignatureLabel && uid == kClaimSignatureUuid) {
        if (box.Holds<SuperBox>()) {
          claim_signature_box = &box.Get<SuperBox>();
        }
      }
    }
  }

  // Claim box should be present and it shall consist of a single CBOR content
  // type. Extract the CBOR content type from the claim box if these
  // conditions are met, otherwise update the failure status.

  absl::string_view claim_cbor = "";
  if (!claim_box.has_value()) {
    validation_tracker.RecordFailure(FailureStatusCode::kClaimMissing,
                                     {.url = claim_box_label});
  } else {
    auto result = ExtractCbor(*claim_box);
    if (!result.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kClaimCborInvalid,
                                       {.url = claim_box_label});
    } else {
      claim_cbor = *result;
    }
  }

  // Parse the claim CBOR as a map and validate the signature field.
  // The signature URI must refer to a location within the same C2PA Manifest
  // box (a self#jumbf location). Moreover, since the claim signature label
  // must be `c2pa.signature`, this implies that the signature URI should be
  // equal to `self#jumbf:c2pa.signature`.

  AssertionUris assertion_uris;
  std::optional<cbor::MapView> claim_map;
  auto claim_result = cbor::Parse(claim_cbor);
  if (!claim_result.ok()) {
    validation_tracker.RecordFailure(FailureStatusCode::kClaimCborInvalid,
                                     {.url = claim_box_label});
  } else {
    auto claim_map_result = (*claim_result)->AsMap();
    if (!claim_map_result.ok()) {
      validation_tracker.RecordFailure(FailureStatusCode::kClaimCborInvalid,
                                       {.url = claim_box_label});
    } else {
      // Validate the signature field.
      claim_map = *claim_map_result;
      auto signature_uri = claim_map->GetString(kSignatureKey);
      if (!signature_uri.ok()) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kClaimMalformed,
            {.url = claim_box_label,
             .explanation = "Claim is missing signature URI"});
      } else if (!IsValidSignatureUri(*signature_uri, manifest)) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kClaimSignatureMissing,
            {.url = kClaimSignatureLabel});
      }
      // Extract the optional `alg` field.
      assertion_uris.default_algorithm = claim_map->GetOptionalString(kAlgKey);
      // Extract the required `created_assertions` field.
      assertion_uris.created_assertions =
          claim_map->GetOptionalArray(kCreatedAssertionsKey);
      // Extract the optional `gathered_assertions` field.
      assertion_uris.gathered_assertions =
          claim_map->GetOptionalArray(kGatheredAssertionsKey);
      // Extract the optional `redacted_assertions` field
      assertion_uris.redacted_assertions =
          claim_map->GetOptionalArray(kRedactedAssertionsKey);
      // Confirm that the `created_assertions` field is set. This field is
      // required in c2pa.claim.v2.
      if (!assertion_uris.created_assertions.has_value()) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kClaimMalformed,
            {.url = claim_box_label,
             .explanation = "Claim is missing created assertions"});
      }
    }
  }

  // Claim signature box should be present and it shall consist of a single
  // CBOR content type. Extract the CBOR content type from the claim signature
  // box if these conditions are met, otherwise update the failure status.

  std::optional<absl::string_view> claim_signature_cbor;
  if (!claim_signature_box.has_value()) {
    validation_tracker.RecordFailure(FailureStatusCode::kClaimSignatureMissing,
                                     {.url = kClaimSignatureLabel});
  } else {
    auto result = ExtractCbor(*claim_signature_box);
    if (!result.ok()) {
      validation_tracker.RecordFailure(
          FailureStatusCode::kClaimSignatureMissing,
          {.url = kClaimSignatureLabel});
    } else {
      claim_signature_cbor = *result;
    }
  }

  std::optional<SignatureInfo> signature_info;
  if (claim_signature_cbor.has_value() && !claim_cbor.empty()) {
    CoseVerificationResult verification_result =
        cose_verifier_.Verify(*claim_signature_cbor, claim_cbor);
    if (verification_result.has_signature_info()) {
      signature_info = verification_result.signature_info();
    }
    validation_tracker.MergeStatuses(verification_result.validation_status());
    if (!verification_result.has_signature_info() &&
        !validation_tracker.HasFailures()) {
      LOG_EVERY_N_SEC(ERROR, 60) << "Signature verification "
                                    "failed but no failure was recorded";
      validation_tracker.RecordFailure(FailureStatusCode::kGoogleInternalError,
                                       {.url = kClaimSignatureLabel});
    }
  } else {
    validation_tracker.RecordFailure(FailureStatusCode::kClaimSignatureMissing,
                                     {.url = kClaimSignatureLabel});
  }

  ClaimValidatorImpl::ValidateAssertionResult validate_assertion_result;
  if (claim_box.has_value()) {
    validate_assertion_result =
        ValidateAssertions(assertion_uris, validation_tracker);
  }

  if (validation_tracker.HasFailures()) {
    return std::nullopt;
  }

  auto options = CreateClaimOptions{
      .label =
          claim_box.has_value()
              ? std::string(claim_box.value()->description.label.value_or(""))
              : "",
      .claim_map = *claim_map,
      .created_assertions =
          absl::MakeSpan(validate_assertion_result.created_assertions),
      .gathered_assertions =
          absl::MakeSpan(validate_assertion_result.gathered_assertions),
      .redacted_assertions =
          absl::MakeSpan(validate_assertion_result.redacted_assertions),
      .signature_info = signature_info,
      .default_algorithm = assertion_uris.default_algorithm,
  };
  return CreateClaim(options, validation_tracker);
}

ClaimValidatorImpl::ValidateAssertionResult
ClaimValidatorImpl::ValidateAssertions(
    const AssertionUris& assertion_uris,
    ValidationTracker& validation_tracker) const {
  // Parse CBOR maps in hashed URI arrays
  std::vector<HashedUriInternal> created_assertions, gathered_assertions;
  ClaimValidatorImpl::ValidateAssertionResult result;
  if (assertion_uris.created_assertions.has_value()) {
    created_assertions = ParseHashedUriArray(*assertion_uris.created_assertions,
                                             validation_tracker);
  }
  if (assertion_uris.gathered_assertions.has_value()) {
    gathered_assertions = ParseHashedUriArray(
        *assertion_uris.gathered_assertions, validation_tracker);
  }
  for (const auto& a : created_assertions) {
    result.created_assertions.push_back(
        a.ToProto(assertion_uris.default_algorithm));
  }
  for (const auto& a : gathered_assertions) {
    result.gathered_assertions.push_back(
        a.ToProto(assertion_uris.default_algorithm));
  }
  std::vector<std::string> redacted_assertions;
  if (assertion_uris.redacted_assertions.has_value()) {
    for (int i = 0; i < assertion_uris.redacted_assertions->size(); ++i) {
      auto uri = assertion_uris.redacted_assertions->GetString(i);
      if (!uri.ok()) {
        validation_tracker.RecordFailure(FailureStatusCode::kHashedUriMissing,
                                         {});
      } else {
        redacted_assertions.push_back(std::string(*uri));
      }
    }
  }
  result.redacted_assertions = redacted_assertions;
  return result;
}

}  // namespace credentio
