// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/unexportable_keys/mojom/unexportable_keys_mojom_traits.h"

#include "base/notreached.h"
#include "base/unguessable_token.h"
#include "components/unexportable_keys/background_task_priority.h"
#include "components/unexportable_keys/mojom/unexportable_key_service.mojom.h"
#include "components/unexportable_keys/service_error.h"
#include "crypto/signature_verifier.h"
#include "crypto/unexportable_key.h"
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/mojom/base/unguessable_token.mojom.h"

namespace mojo {
unexportable_keys::mojom::SignatureAlgorithm
EnumTraits<unexportable_keys::mojom::SignatureAlgorithm,
           crypto::SignatureVerifier::SignatureAlgorithm>::
    ToMojom(crypto::SignatureVerifier::SignatureAlgorithm algo) {
  switch (algo) {
    case crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
      return unexportable_keys::mojom::SignatureAlgorithm::RSA_PKCS1_SHA1;
    case crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
      return unexportable_keys::mojom::SignatureAlgorithm::RSA_PKCS1_SHA256;
    case crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
      return unexportable_keys::mojom::SignatureAlgorithm::ECDSA_SHA256;
    case crypto::SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
      return unexportable_keys::mojom::SignatureAlgorithm::RSA_PSS_SHA256;
  }
}

crypto::SignatureVerifier::SignatureAlgorithm
mojo::EnumTraits<unexportable_keys::mojom::SignatureAlgorithm,
                 crypto::SignatureVerifier::SignatureAlgorithm>::
    FromMojom(unexportable_keys::mojom::SignatureAlgorithm mojo_algo) {
  switch (mojo_algo) {
    case unexportable_keys::mojom::SignatureAlgorithm::RSA_PKCS1_SHA1:
      return crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1;
    case unexportable_keys::mojom::SignatureAlgorithm::RSA_PKCS1_SHA256:
      return crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256;
    case unexportable_keys::mojom::SignatureAlgorithm::ECDSA_SHA256:
      return crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256;
    case unexportable_keys::mojom::SignatureAlgorithm::RSA_PSS_SHA256:
      return crypto::SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256;
  }
  NOTREACHED();
}

unexportable_keys::mojom::BackgroundTaskPriority
EnumTraits<unexportable_keys::mojom::BackgroundTaskPriority,
           unexportable_keys::BackgroundTaskPriority>::
    ToMojom(unexportable_keys::BackgroundTaskPriority priority) {
  switch (priority) {
    case unexportable_keys::BackgroundTaskPriority::kBestEffort:
      return unexportable_keys::mojom::BackgroundTaskPriority::kBestEffort;
    case unexportable_keys::BackgroundTaskPriority::kUserBlocking:
      return unexportable_keys::mojom::BackgroundTaskPriority::kUserBlocking;
    case unexportable_keys::BackgroundTaskPriority::kUserVisible:
      return unexportable_keys::mojom::BackgroundTaskPriority::kUserVisible;
  }
}

unexportable_keys::BackgroundTaskPriority
EnumTraits<unexportable_keys::mojom::BackgroundTaskPriority,
           unexportable_keys::BackgroundTaskPriority>::
    FromMojom(unexportable_keys::mojom::BackgroundTaskPriority mojo_priority) {
  switch (mojo_priority) {
    case unexportable_keys::mojom::BackgroundTaskPriority::kBestEffort:
      return unexportable_keys::BackgroundTaskPriority::kBestEffort;
    case unexportable_keys::mojom::BackgroundTaskPriority::kUserVisible:
      return unexportable_keys::BackgroundTaskPriority::kUserVisible;
    case unexportable_keys::mojom::BackgroundTaskPriority::kUserBlocking:
      return unexportable_keys::BackgroundTaskPriority::kUserBlocking;
  }
  NOTREACHED();
}

unexportable_keys::mojom::ServiceError EnumTraits<
    unexportable_keys::mojom::ServiceError,
    unexportable_keys::ServiceError>::ToMojom(unexportable_keys::ServiceError
                                                  error) {
  switch (error) {
    case unexportable_keys::ServiceError::kAlgorithmNotSupported:
      return unexportable_keys::mojom::ServiceError::kAlgorithmNotSupported;
    case unexportable_keys::ServiceError::kCryptoApiFailed:
      return unexportable_keys::mojom::ServiceError::kCryptoApiFailed;
    case unexportable_keys::ServiceError::kVerifySignatureFailed:
      return unexportable_keys::mojom::ServiceError::kVerifySignatureFailed;
    case unexportable_keys::ServiceError::kKeyCollision:
      return unexportable_keys::mojom::ServiceError::kKeyCollision;
    case unexportable_keys::ServiceError::kKeyNotFound:
      return unexportable_keys::mojom::ServiceError::kKeyNotFound;
    case unexportable_keys::ServiceError::kKeyNotReady:
      return unexportable_keys::mojom::ServiceError::kKeyNotReady;
    case unexportable_keys::ServiceError::kNoKeyProvider:
      return unexportable_keys::mojom::ServiceError::kNoKeyProvider;
    case unexportable_keys::ServiceError::kOperationNotSupported:
      return unexportable_keys::mojom::ServiceError::kOperationNotSupported;
    case unexportable_keys::ServiceError::kOperationCancelled:
      return unexportable_keys::mojom::ServiceError::kOperationCancelled;
  }
}

unexportable_keys::ServiceError
EnumTraits<unexportable_keys::mojom::ServiceError,
           unexportable_keys::ServiceError>::
    FromMojom(unexportable_keys::mojom::ServiceError input) {
  switch (input) {
    case unexportable_keys::mojom::ServiceError::kAlgorithmNotSupported:
      return unexportable_keys::ServiceError::kAlgorithmNotSupported;
    case unexportable_keys::mojom::ServiceError::kCryptoApiFailed:
      return unexportable_keys::ServiceError::kCryptoApiFailed;
    case unexportable_keys::mojom::ServiceError::kVerifySignatureFailed:
      return unexportable_keys::ServiceError::kVerifySignatureFailed;
    case unexportable_keys::mojom::ServiceError::kKeyCollision:
      return unexportable_keys::ServiceError::kKeyCollision;
    case unexportable_keys::mojom::ServiceError::kKeyNotFound:
      return unexportable_keys::ServiceError::kKeyNotFound;
    case unexportable_keys::mojom::ServiceError::kKeyNotReady:
      return unexportable_keys::ServiceError::kKeyNotReady;
    case unexportable_keys::mojom::ServiceError::kNoKeyProvider:
      return unexportable_keys::ServiceError::kNoKeyProvider;
    case unexportable_keys::mojom::ServiceError::kOperationNotSupported:
      return unexportable_keys::ServiceError::kOperationNotSupported;
    case unexportable_keys::mojom::ServiceError::kOperationCancelled:
      return unexportable_keys::ServiceError::kOperationCancelled;
  }
  NOTREACHED();
}

bool StructTraits<unexportable_keys::mojom::UnexportableSigningKeyIdDataView,
                  unexportable_keys::UnexportableSigningKeyId>::
    Read(unexportable_keys::mojom::UnexportableSigningKeyIdDataView data,
         unexportable_keys::UnexportableSigningKeyId* output) {
  base::UnguessableToken key_id;
  if (!data.ReadKeyId(&key_id)) {
    // Failed to read the underlying UnguessableToken.
    return false;
  }
  // Construct the base::TokenType from the UnguessableToken.
  *output = unexportable_keys::UnexportableSigningKeyId(key_id);
  return true;
}

bool StructTraits<
    unexportable_keys::mojom::UnexportableAttestationKeyIdDataView,
    unexportable_keys::UnexportableAttestationKeyId>::
    Read(unexportable_keys::mojom::UnexportableAttestationKeyIdDataView data,
         unexportable_keys::UnexportableAttestationKeyId* output) {
  base::UnguessableToken key_id;
  if (!data.ReadKeyId(&key_id)) {
    return false;
  }
  *output = unexportable_keys::UnexportableAttestationKeyId(key_id);
  return true;
}

unexportable_keys::mojom::AttestationFormat
EnumTraits<unexportable_keys::mojom::AttestationFormat,
           crypto::AttestationStatement::Format>::
    ToMojom(crypto::AttestationStatement::Format format) {
  switch (format) {
    case crypto::AttestationStatement::Format::kTpm:
      return unexportable_keys::mojom::AttestationFormat::kTpm;
    case crypto::AttestationStatement::Format::kSecureEnclave:
      return unexportable_keys::mojom::AttestationFormat::kSecureEnclave;
  }
}

crypto::AttestationStatement::Format
EnumTraits<unexportable_keys::mojom::AttestationFormat,
           crypto::AttestationStatement::Format>::
    FromMojom(unexportable_keys::mojom::AttestationFormat mojo_format) {
  switch (mojo_format) {
    case unexportable_keys::mojom::AttestationFormat::kTpm:
      return crypto::AttestationStatement::Format::kTpm;
    case unexportable_keys::mojom::AttestationFormat::kSecureEnclave:
      return crypto::AttestationStatement::Format::kSecureEnclave;
  }
  NOTREACHED();
}

bool StructTraits<unexportable_keys::mojom::AttestationStatementDataView,
                  crypto::AttestationStatement>::
    Read(unexportable_keys::mojom::AttestationStatementDataView data,
         crypto::AttestationStatement* output) {
  if (!data.ReadFormat(&output->format)) {
    return false;
  }
  if (!data.ReadStatement(&output->statement)) {
    return false;
  }
  if (!data.ReadSignature(&output->signature)) {
    return false;
  }
  return true;
}
}  // namespace mojo
