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

#include <memory>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "claim/local_signer.h"
#include "claim/validator.h"
#include "cose/verifier.h"
#include "crypto/crypto_read_handler.h"
#include "crypto/crypto_write_handler.h"
#include "crypto/default/default_crypto_read_handler.h"
#include "crypto/default/hasher.h"
#include "generator/generator.h"
#include "generator/generator_factory.h"
#include "jumbf/box.h"
#include "jumbf/parse.h"
#include "proto/generator.pb.h"
#include "proto/generator_info.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "testing/create_test_crypto_write_handler.h"
#include "testing/proto_test_utils.h"
#include "testing/test_validation_tracker.h"
#include "validator/manifest_store_validator_impl.h"

namespace credentio {

absl::StatusOr<std::string> CreateSimpleManifestStoreBytes(
    const SimpleManifestStoreOptions& options) {
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<CryptoWriteHandler> crypto_write_handler,
      CreateTestCryptoWriteHandler({
          .clock = options.clock,
          .disable_timestamping = options.disable_timestamping,
      }));
  LocalClaimSigner claim_signer(crypto_write_handler.get(),
                                &DefaultHasherFactory());
  GeneratorInfo generator_info;
  if (options.generator_info.has_value()) {
    generator_info = *options.generator_info;
  } else {
    generator_info.set_name("Test C2PA Generator");
  }
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<ManifestStoreGenerator> manifest_store_generator,
      CreateGenerator({
          .generator_info = std::move(generator_info),
          .signing_claim_signer = &claim_signer,
          .template_claim_signer = &claim_signer,
          .uuid_generator = options.uuid_generator,
      }));
  auto request = credentio_testing::ParseTextProtoOrDie<
      GenerateManifestStoreRequest>(R"pb(
    instance_id: "12345678-1234-1234-1234-123456789012"
    hard_binding {
      box_hash {
        alg: "some alg"
        boxes { names: "some name" names: "other name" hash: "some hash" }
      }
    }
    actions {
      created {
        action_metadata {
          software_agent { name: "test generator" }
          description: "created for testing"
        }
        digital_source_type: "https://cv.iptc.org/newscodes/digitalsourcetype/computationalCapture"
      }
    }
  )pb");
  ABSL_ASSIGN_OR_RETURN(
      auto generated, manifest_store_generator->GenerateManifestStore(request));
  return std::string(generated.manifest_store());
}

absl::StatusOr<std::unique_ptr<PartialValidationResultProto>>
ValidateManifestStore(absl::string_view manifest_store_bytes) {
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<CryptoReadHandler> crypto_read_handler,
      CreateDefaultCryptoReadHandler({
          .trust_environment = CryptoReadHandler::TrustEnvironment::kAny,
      }));
  ManifestStoreValidatorImpl validator({
      .crypto_read_handler = std::move(crypto_read_handler),
  });
  return validator.Validate(manifest_store_bytes);
}

absl::StatusOr<Claim> ValidateClaim(absl::string_view manifest_store_bytes) {
  ABSL_ASSIGN_OR_RETURN(auto manifest_store_box,
                        jumbf::ConsumeSuperBox(&manifest_store_bytes, 9));
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<CryptoReadHandler> crypto_read_handler,
      CreateDefaultCryptoReadHandler({
          .trust_environment = CryptoReadHandler::TrustEnvironment::kAny,
      }));
  std::unique_ptr<CoseVerifier> cose_verifier = CreateCoseVerifier(
      {.crypto_read_handler = std::move(crypto_read_handler)});
  ClaimValidatorImpl validator(cose_verifier.get());
  TestValidationTracker validation_tracker;
  if (manifest_store_box.contents.empty()) {
    return absl::InvalidArgumentError("Manifest store is empty");
  }
  if (!manifest_store_box.contents.back().Holds<jumbf::SuperBox>()) {
    return absl::InvalidArgumentError("Last box is not a super box");
  }
  jumbf::SuperBox manifest_box =
      manifest_store_box.contents.back().Get<jumbf::SuperBox>();
  auto result = validator.Validate(manifest_box, validation_tracker.tracker());
  if (!validation_tracker.GetFailures().empty()) {
    return absl::InvalidArgumentError(
        absl::StrJoin(validation_tracker.GetFailureStatuses(), ";"));
  }
  return result.value();
}

}  // namespace credentio
