// 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 <fstream>
#include <iostream>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <utility>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/flags/usage.h"
#include "absl/log/initialize.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "crypto/crypto_read_handler.h"
#include "crypto/default/default_crypto_read_handler.h"
#include "google/protobuf/text_format.h"
#include "riegeli/bytes/cfile_reader.h"
#include "utils/media_type.h"
#include "validator/asset_validator_impl.h"
#include "validator/result.h"
#include "validator/validator_options.h"

ABSL_FLAG(std::string, asset, "",
          "Path to the asset file to validate (Required).");
ABSL_FLAG(
    std::string, claim_signer_trust, "",
    "Path to PEM file containing claim signer trust anchors (for C2PA "
    "2.2+ strict EKU compliance). If not provided, then the validator will "
    "default to skip trust checks.");
ABSL_FLAG(std::string, tsa_trust, "",
          "Path to PEM file containing TSA trust anchors. If not provided, "
          "then the validator will default to skip TSA trust checks.");

namespace {

absl::StatusOr<std::string> GetContents(absl::string_view file_path) {
  std::ifstream f(std::string(file_path), std::ios::binary);
  if (!f.is_open()) {
    return absl::NotFoundError(
        absl::StrCat("Failed to open file: ", file_path));
  }
  std::stringstream buffer;
  buffer << f.rdbuf();
  return buffer.str();
}

}  // namespace

int main(int argc, char* argv[]) {
  absl::SetProgramUsageMessage(
      "Validates C2PA asset files and prints validation results.\n"
      "Usage:\n  c2pa_validate --asset=<path_to_asset> "
      "[--claim_signer_trust=<pem_path>] [--tsa_trust=<pem_path>]");
  absl::InitializeLog();
  absl::ParseCommandLine(argc, argv);

  const std::string asset_path = absl::GetFlag(FLAGS_asset);
  if (asset_path.empty()) {
    std::cerr << "Error: --asset flag is required.\n";
    return 1;
  }

  const std::string claim_signer_trust_path =
      absl::GetFlag(FLAGS_claim_signer_trust);
  const std::string tsa_trust_path = absl::GetFlag(FLAGS_tsa_trust);

  credentio::DefaultCryptoReadHandlerOptions crypto_options;
  std::string claim_signer_trust_pem;
  std::string tsa_trust_pem;

  if (!claim_signer_trust_path.empty()) {
    absl::StatusOr<std::string> pem = GetContents(claim_signer_trust_path);
    if (!pem.ok()) {
      std::cerr << "Error reading claim signer trust file: " << pem.status()
                << "\n";
      return 1;
    }
    claim_signer_trust_pem = *std::move(pem);
    crypto_options.claim_signer_trust_anchors_pem = claim_signer_trust_pem;
  } else {
    std::cerr << "WARNING: --claim_signer_trust is not provided. Skipping "
                 "claim signer trust checks.\n";
    crypto_options.skip_claim_signer_trust_checks_for_test = true;
  }

  if (!tsa_trust_path.empty()) {
    absl::StatusOr<std::string> pem = GetContents(tsa_trust_path);
    if (!pem.ok()) {
      std::cerr << "Error reading TSA trust file: " << pem.status() << "\n";
      return 1;
    }
    tsa_trust_pem = *std::move(pem);
    crypto_options.tsa_trust_anchors_pem = tsa_trust_pem;
  } else {
    std::cerr
        << "WARNING: --tsa_trust is not provided. Skipping TSA trust checks.\n";
    crypto_options.skip_tsa_trust_checks_for_test = true;
  }

  absl::StatusOr<std::unique_ptr<credentio::CryptoReadHandler>>
      crypto_read_handler =
          credentio::CreateDefaultCryptoReadHandler(crypto_options);
  if (!crypto_read_handler.ok()) {
    std::cerr << "Error creating crypto read handler: "
              << crypto_read_handler.status() << "\n";
    return 1;
  }

  credentio::AssetValidatorImpl validator(credentio::ValidatorOptions{
      .crypto_read_handler = *std::move(crypto_read_handler),
  });

  riegeli::CFileReader<> reader(asset_path);
  if (!reader.ok()) {
    std::cerr << "Error opening asset file: " << reader.status() << "\n";
    return 1;
  }

  std::optional<absl::string_view> media_type_opt;
  const absl::StatusOr<std::string> media_type =
      credentio::MediaType(asset_path);
  if (media_type.ok()) {
    media_type_opt = *media_type;
  } else {
    std::cerr << "Error determining media type: " << media_type.status()
              << "\n";
  }

  const absl::StatusOr<std::unique_ptr<credentio::ValidationResult>> result =
      validator.Validate(reader, media_type_opt);
  if (!result.ok()) {
    std::cerr << "Validation failed: " << result.status() << "\n";
    return 1;
  }

  std::cout << "Validation successful!\n";
  std::string text_format;
  if (google::protobuf::TextFormat::PrintToString((*result)->proto(),
                                                  &text_format)) {
    std::cout << "Validation Result:\n" << text_format << "\n";
  } else {
    std::cerr << "Failed to convert result proto to text format.\n";
    return 1;
  }

  return 0;
}
