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

#include "device/fido/fido_hid_message.h"

#include <algorithm>
#include <numeric>
#include <utility>

#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "device/fido/fido_parsing_utils.h"

namespace device {

// static
base::Optional<FidoHidMessage> FidoHidMessage::Create(
    uint32_t channel_id,
    FidoHidDeviceCommand type,
    base::span<const uint8_t> data) {
  if (data.size() > kHidMaxMessageSize)
    return base::nullopt;

  switch (type) {
    case FidoHidDeviceCommand::kPing:
      break;
    case FidoHidDeviceCommand::kMsg:
    case FidoHidDeviceCommand::kCbor: {
      if (data.empty())
        return base::nullopt;
      break;
    }

    case FidoHidDeviceCommand::kCancel:
    case FidoHidDeviceCommand::kWink: {
      if (!data.empty())
        return base::nullopt;
      break;
    }
    case FidoHidDeviceCommand::kLock: {
      if (data.size() != 1 || data[0] > kHidMaxLockSeconds)
        return base::nullopt;
      break;
    }
    case FidoHidDeviceCommand::kInit: {
      if (data.size() != 8)
        return base::nullopt;
      break;
    }
    case FidoHidDeviceCommand::kKeepAlive:
    case FidoHidDeviceCommand::kError:
      if (data.size() != 1)
        return base::nullopt;
  }

  return FidoHidMessage(channel_id, type, data);
}

// static
base::Optional<FidoHidMessage> FidoHidMessage::CreateFromSerializedData(
    base::span<const uint8_t> serialized_data) {
  size_t remaining_size = 0;
  if (serialized_data.size() > kHidPacketSize ||
      serialized_data.size() < kHidInitPacketHeaderSize)
    return base::nullopt;

  auto init_packet = FidoHidInitPacket::CreateFromSerializedData(
      serialized_data, &remaining_size);

  if (init_packet == nullptr)
    return base::nullopt;

  return FidoHidMessage(std::move(init_packet), remaining_size);
}

FidoHidMessage::FidoHidMessage(FidoHidMessage&& that) = default;

FidoHidMessage& FidoHidMessage::operator=(FidoHidMessage&& other) = default;

FidoHidMessage::~FidoHidMessage() = default;

bool FidoHidMessage::MessageComplete() const {
  return remaining_size_ == 0;
}

std::vector<uint8_t> FidoHidMessage::GetMessagePayload() const {
  std::vector<uint8_t> data;
  size_t data_size = 0;
  for (const auto& packet : packets_) {
    data_size += packet->GetPacketPayload().size();
  }
  data.reserve(data_size);

  for (const auto& packet : packets_) {
    const auto& packet_data = packet->GetPacketPayload();
    data.insert(std::end(data), packet_data.cbegin(), packet_data.cend());
  }

  return data;
}

std::vector<uint8_t> FidoHidMessage::PopNextPacket() {
  if (packets_.empty())
    return {};

  std::vector<uint8_t> data = packets_.front()->GetSerializedData();
  packets_.pop_front();
  return data;
}

bool FidoHidMessage::AddContinuationPacket(base::span<const uint8_t> buf) {
  size_t remaining_size = remaining_size_;
  auto cont_packet =
      FidoHidContinuationPacket::CreateFromSerializedData(buf, &remaining_size);

  // Reject packets with a different channel id.
  if (!cont_packet || channel_id_ != cont_packet->channel_id())
    return false;

  remaining_size_ = remaining_size;
  packets_.push_back(std::move(cont_packet));
  return true;
}

size_t FidoHidMessage::NumPackets() const {
  return packets_.size();
}

FidoHidMessage::FidoHidMessage(uint32_t channel_id,
                               FidoHidDeviceCommand type,
                               base::span<const uint8_t> data)
    : channel_id_(channel_id) {
  uint8_t sequence = 0;

  auto init_data = data.first(std::min(kHidInitPacketDataSize, data.size()));
  packets_.push_back(std::make_unique<FidoHidInitPacket>(
      channel_id, type,
      std::vector<uint8_t>(init_data.begin(), init_data.end()), data.size()));
  data = data.subspan(init_data.size());

  for (auto cont_data :
       fido_parsing_utils::SplitSpan(data, kHidContinuationPacketDataSize)) {
    packets_.push_back(std::make_unique<FidoHidContinuationPacket>(
        channel_id, sequence++, fido_parsing_utils::Materialize(cont_data)));
  }
}

FidoHidMessage::FidoHidMessage(std::unique_ptr<FidoHidInitPacket> init_packet,
                               size_t remaining_size)
    : remaining_size_(remaining_size) {
  channel_id_ = init_packet->channel_id();
  cmd_ = init_packet->command();
  packets_.push_back(std::move(init_packet));
}

}  // namespace device
