// 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.
//

#ifndef THIRD_PARTY_CREDENTIO_COSE_SIG_STRUCTURE_H_
#define THIRD_PARTY_CREDENTIO_COSE_SIG_STRUCTURE_H_

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

#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "crypto/algorithms.h"

namespace credentio {

struct ProtectedHeader {
  SigningAlgorithm alg;
  std::vector<std::string> certificate_chain;

  bool operator==(const ProtectedHeader& other) const {
    return alg == other.alg && certificate_chain == other.certificate_chain;
  }
};

// Encodes ProtectedHeader as a serialized CBOR map.
absl::StatusOr<std::string> EncodeProtectedHeader(
    const ProtectedHeader& protected_header);

// Decodes ProtectedHeader serialized as a CBOR map.
absl::StatusOr<ProtectedHeader> DecodeProtectedHeader(absl::string_view cbor);

// Sig_structure with sign_protected field omitted.
// Sig_structure = [
//   context : "Signature" / "Signature1" / "CounterSignature",
//   body_protected : empty_or_serialized_map,
//   external_aad : bstr,
//   payload : bstr
// ]
struct Sig1Structure {
  std::string context;
  std::string body_protected;
  std::string external_aad;
  std::string payload;

  bool operator==(const Sig1Structure& other) const {
    return context == other.context && body_protected == other.body_protected &&
           external_aad == other.external_aad && payload == other.payload;
  }
};

// Encodes Sig1Structure to a CBOR byte string.
std::string EncodeSig1Structure(const Sig1Structure& sig_structure);

// See
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_storing_the_time_stamp
struct TstToken {
  std::string val;  // bstr in the CBOR.

  bool operator==(const TstToken& other) const { return val == other.val; }
};

// See
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_storing_the_time_stamp
struct TstContainer {
  std::vector<TstToken> tst_tokens;  // contents of 'tstTokens' CBOR array.

  bool operator==(const TstContainer& other) const {
    return tst_tokens == other.tst_tokens;
  }
};

struct UnprotectedHeader {
  // See
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_storing_the_time_stamp.
  std::optional<TstContainer> sig_tst2;  // contents of 'sigTst2' CBOR map.
  // DEPRECATED. DO NOT GENERATE. Contents of 'sigTst' CBOR map.
  std::optional<TstContainer> sig_tst;
  // DEPRECATED. DO NOT GENERATE. Contents of certificate chain, which should be
  // in the protected header.
  std::vector<std::string> certificate_chain;
  // See
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_certificate_revocation.
  std::vector<std::string> ocsp_responses;  // contents of `ocspVals` array.
  // See
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_going_back_and_filling_in
  // about padding.
  std::optional<std::string> pad;   // contents of 'pad' CBOR bstr.
  std::optional<std::string> pad2;  // contents of 'pad2' CBOR bstr.

  bool operator==(const UnprotectedHeader& other) const {
    return sig_tst2 == other.sig_tst2 && sig_tst == other.sig_tst &&
           certificate_chain == other.certificate_chain &&
           ocsp_responses == other.ocsp_responses && pad == other.pad &&
           pad2 == other.pad2;
  }
};

// COSE_Sign1 = [
//     protected: bstr,
//     unprotected: map,
//     payload: bstr / nil,
//     signature: bstr
// ]
struct CoseSign1TaggedStructure {
  std::string protected_header;
  UnprotectedHeader unprotected_header;
  std::optional<std::string> payload = std::nullopt;
  std::string signature;
  // Returns the signature as a CBOR-encoded byte string.
  std::string signature_bstr() const;

  bool operator==(const CoseSign1TaggedStructure& other) const {
    return protected_header == other.protected_header &&
           unprotected_header == other.unprotected_header &&
           payload == other.payload && signature == other.signature;
  }
};

std::string EncodeCoseSign1TaggedStructure(const CoseSign1TaggedStructure& s);
absl::StatusOr<CoseSign1TaggedStructure> DecodeCoseSign1TaggedStructure(
    absl::string_view cbor);
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_COSE_SIG_STRUCTURE_H_
