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

#ifndef THIRD_PARTY_BLINK_PUBLIC_MOJOM_AUTHENTICATOR_MOJOM_TRAITS_H_
#define THIRD_PARTY_BLINK_PUBLIC_MOJOM_AUTHENTICATOR_MOJOM_TRAITS_H_

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

#include "base/component_export.h"
#include "base/containers/flat_tree.h"
#include "base/notreached.h"
#include "device/fido/public/authenticator_selection_criteria.h"
#include "device/fido/public/fido_constants.h"
#include "device/fido/public/fido_transport_protocol.h"
#include "device/fido/public/public_key_credential_descriptor.h"
#include "device/fido/public/public_key_credential_params.h"
#include "device/fido/public/public_key_credential_rp_entity.h"
#include "device/fido/public/public_key_credential_user_entity.h"
#include "mojo/public/cpp/bindings/array_traits_stl.h"
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "third_party/blink/public/common/common_export.h"
#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-shared.h"

namespace mojo {

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::AuthenticatorTransport,
               device::FidoTransportProtocol> {
  static blink::mojom::AuthenticatorTransport ToMojom(
      device::FidoTransportProtocol input);
  static device::FidoTransportProtocol FromMojom(
      blink::mojom::AuthenticatorTransport input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::PublicKeyCredentialType, device::CredentialType> {
  static blink::mojom::PublicKeyCredentialType ToMojom(
      device::CredentialType input);
  static device::CredentialType FromMojom(
      blink::mojom::PublicKeyCredentialType input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    StructTraits<blink::mojom::PublicKeyCredentialParametersDataView,
                 device::PublicKeyCredentialParams::CredentialInfo> {
  static device::CredentialType type(
      const device::PublicKeyCredentialParams::CredentialInfo& in) {
    return in.type;
  }

  static int32_t algorithm_identifier(
      const device::PublicKeyCredentialParams::CredentialInfo& in) {
    return in.algorithm;
  }

  static bool Read(blink::mojom::PublicKeyCredentialParametersDataView data,
                   device::PublicKeyCredentialParams::CredentialInfo* out);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    StructTraits<blink::mojom::PublicKeyCredentialDescriptorDataView,
                 device::PublicKeyCredentialDescriptor> {
  static device::CredentialType type(
      const device::PublicKeyCredentialDescriptor& in) {
    return in.credential_type;
  }

  static const std::vector<uint8_t>& id(
      const device::PublicKeyCredentialDescriptor& in) {
    return in.id;
  }

  static const std::vector<device::FidoTransportProtocol> transports(
      const device::PublicKeyCredentialDescriptor& in) {
    std::vector<device::FidoTransportProtocol> protocols;
    for (const auto& protocol : in.transports) {
      protocols.push_back(protocol);
    }
    return protocols;
  }

  static bool Read(blink::mojom::PublicKeyCredentialDescriptorDataView data,
                   device::PublicKeyCredentialDescriptor* out);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::AuthenticatorAttachment,
               device::AuthenticatorAttachment> {
  static blink::mojom::AuthenticatorAttachment ToMojom(
      device::AuthenticatorAttachment input);
  static device::AuthenticatorAttachment FromMojom(
      blink::mojom::AuthenticatorAttachment input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::ResidentKeyRequirement,
               device::ResidentKeyRequirement> {
  static blink::mojom::ResidentKeyRequirement ToMojom(
      device::ResidentKeyRequirement input);
  static device::ResidentKeyRequirement FromMojom(
      blink::mojom::ResidentKeyRequirement input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::UserVerificationRequirement,
               device::UserVerificationRequirement> {
  static blink::mojom::UserVerificationRequirement ToMojom(
      device::UserVerificationRequirement input);
  static device::UserVerificationRequirement FromMojom(
      blink::mojom::UserVerificationRequirement input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::LargeBlobSupport, device::LargeBlobSupport> {
  static blink::mojom::LargeBlobSupport ToMojom(device::LargeBlobSupport input);
  static device::LargeBlobSupport FromMojom(
      blink::mojom::LargeBlobSupport input);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    StructTraits<blink::mojom::AuthenticatorSelectionCriteriaDataView,
                 device::AuthenticatorSelectionCriteria> {
  static device::AuthenticatorAttachment authenticator_attachment(
      const device::AuthenticatorSelectionCriteria& in) {
    return in.authenticator_attachment;
  }

  static device::ResidentKeyRequirement resident_key(
      const device::AuthenticatorSelectionCriteria& in) {
    return in.resident_key;
  }

  static device::UserVerificationRequirement user_verification(
      const device::AuthenticatorSelectionCriteria& in) {
    return in.user_verification_requirement;
  }

  static bool Read(blink::mojom::AuthenticatorSelectionCriteriaDataView data,
                   device::AuthenticatorSelectionCriteria* out);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    StructTraits<blink::mojom::PublicKeyCredentialRpEntityDataView,
                 device::PublicKeyCredentialRpEntity> {
  static const std::string& id(const device::PublicKeyCredentialRpEntity& in) {
    return in.id;
  }

  static const std::optional<std::string>& name(
      const device::PublicKeyCredentialRpEntity& in) {
    return in.name;
  }

  static bool Read(blink::mojom::PublicKeyCredentialRpEntityDataView data,
                   device::PublicKeyCredentialRpEntity* out);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    StructTraits<blink::mojom::PublicKeyCredentialUserEntityDataView,
                 device::PublicKeyCredentialUserEntity> {
  static const std::vector<uint8_t>& id(
      const device::PublicKeyCredentialUserEntity& in) {
    return in.id;
  }

  static const std::optional<std::string>& name(
      const device::PublicKeyCredentialUserEntity& in) {
    return in.name;
  }

  static const std::optional<std::string>& display_name(
      const device::PublicKeyCredentialUserEntity& in) {
    return in.display_name;
  }

  static bool Read(blink::mojom::PublicKeyCredentialUserEntityDataView data,
                   device::PublicKeyCredentialUserEntity* out);
};

template <>
struct COMPONENT_EXPORT(AUTHENTICATOR_MOJOM)
    EnumTraits<blink::mojom::AttestationConveyancePreference,
               device::AttestationConveyancePreference> {
  static blink::mojom::AttestationConveyancePreference ToMojom(
      device::AttestationConveyancePreference input);
  static device::AttestationConveyancePreference FromMojom(
      blink::mojom::AttestationConveyancePreference input);
};

}  // namespace mojo

#endif  // THIRD_PARTY_BLINK_PUBLIC_MOJOM_AUTHENTICATOR_MOJOM_TRAITS_H_
