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

#include <memory>
#include <optional>
#include <utility>

#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "cose/cose_sign1.h"
#include "cose/sig_structure.h"
#include "cose/validation_status_util.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "google/protobuf/timestamp.pb.h"
#include "proto/cose_verification_result.pb.h"
#include "proto/signature_info.pb.h"
#include "proto/validation_status.pb.h"

namespace credentio {
namespace {

class CoseVerifierImpl : public CoseVerifier {
 public:
  explicit CoseVerifierImpl(CoseVerifierOptions options)
      : options_(std::move(options)) {}
  CoseVerificationResult Verify(absl::string_view cose_signature,
                                absl::string_view data) const override {
    CoseVerificationResult result;
    ValidationStatusSet* status_set = result.mutable_validation_status();
    absl::StatusOr<CoseSign1TaggedStructure> cose_sign1_struct =
        DecodeCoseSign1TaggedStructure(cose_signature);
    if (!cose_sign1_struct.ok()) {
      RecordStatus(status_set, FailureStatusCode::kSigningCredentialInvalid,
                   {.url = kClaimSignatureLabel,
                    .explanation = cose_sign1_struct.status().ToString()});
      return result;
    }
    auto cose_sign1_verifier = CoseSign1Verifier::Create(
        options_.crypto_read_handler.get(), &DefaultHashCheckerFactory(),
        options_.clock,
        CoseSign1Verifier::Options{
            .check_ocsp_responses = options_.revocation_checks ==
                                    CoseVerifierRevocationChecks::kEnabled,
            .verify_signature = options_.signature_checks ==
                                CoseVerifierSignatureChecks::kEnabled,
        });
    std::optional<SignatureInfo> signature_info = cose_sign1_verifier->Verify(
        *std::move(cose_sign1_struct), data, status_set);
    if (!signature_info.has_value()) {
      // Failure has already been recorded to the tracker by CoseSign1::Verify.
      return result;
    }
    *result.mutable_signature_info() = *std::move(signature_info);

    return result;
  }

 private:
  const CoseVerifierOptions options_;
};

}  // namespace

std::unique_ptr<CoseVerifier> CreateCoseVerifier(CoseVerifierOptions options) {
  CHECK(options.crypto_read_handler);
  return std::make_unique<CoseVerifierImpl>(std::move(options));
}

}  // namespace credentio
