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

#ifndef DEVICE_FIDO_CABLE_PAIRING_H_
#define DEVICE_FIDO_CABLE_PAIRING_H_

#include <stdint.h>

#include <array>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/time/time.h"
#include "device/fido/cable/v2_constants.h"
#include "device/fido/public/fido_constants.h"

namespace cbor {
class Value;
}

namespace device::cablev2 {

// Pairing represents information previously received from a caBLEv2
// authenticator that enables future interactions to skip scanning a QR code.
struct COMPONENT_EXPORT(DEVICE_FIDO) Pairing {
  Pairing();
  ~Pairing();
  Pairing(const Pairing&);
  Pairing& operator=(const Pairing&);

  // Parse builds a `Pairing` from an authenticator message. The signature
  // within the structure is validated by using `local_identity_seed` and
  // `handshake_hash`.
  static std::optional<std::unique_ptr<Pairing>> Parse(
      const cbor::Value& cbor,
      tunnelserver::KnownDomainID domain,
      base::span<const uint8_t, kQRSeedSize> local_identity_seed,
      base::span<const uint8_t, 32> handshake_hash);

  static bool EqualPublicKeys(const std::unique_ptr<Pairing>&,
                              const std::unique_ptr<Pairing>&);

  // tunnel_server_domain is the encoded 16-bit value in the BLE advert.
  tunnelserver::KnownDomainID tunnel_server_domain = kTunnelServer;
  // contact_id is an opaque value that is sent to the tunnel service in order
  // to identify the caBLEv2 authenticator.
  std::vector<uint8_t> contact_id;
  // id is an opaque identifier that is sent via the tunnel service, to the
  // authenticator, to identify this specific pairing.
  std::vector<uint8_t> id;
  // secret is the shared secret that authenticates the desktop to the
  // authenticator.
  std::vector<uint8_t> secret;
  // peer_public_key_x962 is the authenticator's public key.
  std::array<uint8_t, kP256X962Length> peer_public_key_x962{};
  // name is a human-friendly name for the authenticator, specified by that
  // authenticator. (For example "Pixel 3".)
  std::string name;
  // last_updated is populated for pairings learned from Sync.
  base::Time last_updated;
  // from_sync_deviceinfo is true iff this `Pairing` was derived from a
  // DeviceInfo record in Sync, rather than from scanning a QR code. (Note that
  // the results of QR scanning may also be distributed via Sync, but that
  // wouldn't cause this value to be true.)
  bool from_sync_deviceinfo = false;
  // channel_priority is populated when `from_sync_deviceinfo` is true. It
  // contains a higher number for less stable release channels (i.e. Canary is
  // high, development builds are highest).
  int channel_priority = 0;
  // from_new_implementation is true if this Pairing was generated by the new
  // hybrid implementation on Android.
  bool from_new_implementation = false;
};

}  // namespace device::cablev2

#endif  // DEVICE_FIDO_CABLE_PAIRING_H_
