// 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/mock_fido_device.h"

#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/strings/strcat.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/apdu/apdu_response.h"
#include "device/fido/device_response_converter.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_parsing_utils.h"
#include "device/fido/fido_test_data.h"

namespace device {

namespace {
AuthenticatorGetInfoResponse DefaultAuthenticatorInfo() {
  return *ReadCTAPGetInfoResponse(test_data::kTestAuthenticatorGetInfoResponse);
}
}  // namespace

// static
std::unique_ptr<MockFidoDevice> MockFidoDevice::MakeU2f() {
  return std::make_unique<MockFidoDevice>(ProtocolVersion::kU2f, base::nullopt);
}

// static
std::unique_ptr<MockFidoDevice> MockFidoDevice::MakeCtap(
    base::Optional<AuthenticatorGetInfoResponse> device_info) {
  if (!device_info) {
    device_info = DefaultAuthenticatorInfo();
  }
  return std::make_unique<MockFidoDevice>(ProtocolVersion::kCtap,
                                          std::move(*device_info));
}

// static
std::unique_ptr<MockFidoDevice>
MockFidoDevice::MakeU2fWithGetInfoExpectation() {
  auto device = std::make_unique<MockFidoDevice>();
  device->StubGetId();
  device->ExpectCtap2CommandAndRespondWith(
      CtapRequestCommand::kAuthenticatorGetInfo, base::nullopt);
  return device;
}

// static
std::unique_ptr<MockFidoDevice> MockFidoDevice::MakeCtapWithGetInfoExpectation(
    base::Optional<base::span<const uint8_t>> get_info_response) {
  auto device = std::make_unique<MockFidoDevice>();
  device->StubGetId();
  if (!get_info_response) {
    get_info_response = test_data::kTestAuthenticatorGetInfoResponse;
  }
  device->ExpectCtap2CommandAndRespondWith(
      CtapRequestCommand::kAuthenticatorGetInfo, std::move(get_info_response));
  return device;
}

// Matcher to compare the fist byte of the incoming requests.
MATCHER_P(IsCtap2Command, expected_command, "") {
  return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command);
}

MockFidoDevice::MockFidoDevice() : weak_factory_(this) {}
MockFidoDevice::MockFidoDevice(
    ProtocolVersion protocol_version,
    base::Optional<AuthenticatorGetInfoResponse> device_info)
    : MockFidoDevice() {
  set_supported_protocol(protocol_version);
  if (device_info) {
    SetDeviceInfo(std::move(*device_info));
  }
}
MockFidoDevice::~MockFidoDevice() = default;

void MockFidoDevice::TryWink(WinkCallback cb) {
  TryWinkRef(cb);
}

void MockFidoDevice::DeviceTransact(std::vector<uint8_t> command,
                                    DeviceCallback cb) {
  DeviceTransactPtr(command, cb);
}

FidoTransportProtocol MockFidoDevice::DeviceTransport() const {
  return transport_protocol_;
}

base::WeakPtr<FidoDevice> MockFidoDevice::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

void MockFidoDevice::ExpectWinkedAtLeastOnce() {
  EXPECT_CALL(*this, TryWinkRef(::testing::_)).Times(::testing::AtLeast(1));
}

void MockFidoDevice::StubGetId() {
  // Use a counter to keep the device ID unique.
  static size_t i = 0;
  EXPECT_CALL(*this, GetId())
      .WillRepeatedly(
          testing::Return(base::StrCat({"mockdevice", std::to_string(i++)})));
}

void MockFidoDevice::ExpectCtap2CommandAndRespondWith(
    CtapRequestCommand command,
    base::Optional<base::span<const uint8_t>> response,
    base::TimeDelta delay) {
  auto data = fido_parsing_utils::MaterializeOrNull(response);
  auto send_response = [ data(std::move(data)), delay ](DeviceCallback & cb) {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, base::BindOnce(std::move(cb), std::move(data)), delay);
  };

  EXPECT_CALL(*this, DeviceTransactPtr(IsCtap2Command(command), ::testing::_))
      .WillOnce(::testing::WithArg<1>(::testing::Invoke(send_response)));
}

void MockFidoDevice::ExpectCtap2CommandAndRespondWithError(
    CtapRequestCommand command,
    CtapDeviceResponseCode response_code,
    base::TimeDelta delay) {
  std::array<uint8_t, 1> data{base::strict_cast<uint8_t>(response_code)};
  return ExpectCtap2CommandAndRespondWith(std::move(command), data, delay);
}

void MockFidoDevice::ExpectRequestAndRespondWith(
    base::span<const uint8_t> request,
    base::Optional<base::span<const uint8_t>> response,
    base::TimeDelta delay) {
  auto data = fido_parsing_utils::MaterializeOrNull(response);
  auto send_response = [ data(std::move(data)), delay ](DeviceCallback & cb) {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, base::BindOnce(std::move(cb), std::move(data)), delay);
  };

  auto request_as_vector = fido_parsing_utils::Materialize(request);
  EXPECT_CALL(*this,
              DeviceTransactPtr(std::move(request_as_vector), ::testing::_))
      .WillOnce(::testing::WithArg<1>(::testing::Invoke(send_response)));
}

void MockFidoDevice::ExpectCtap2CommandAndDoNotRespond(
    CtapRequestCommand command) {
  EXPECT_CALL(*this, DeviceTransactPtr(IsCtap2Command(command), ::testing::_));
}

void MockFidoDevice::ExpectRequestAndDoNotRespond(
    base::span<const uint8_t> request) {
  auto request_as_vector = fido_parsing_utils::Materialize(request);
  EXPECT_CALL(*this,
              DeviceTransactPtr(std::move(request_as_vector), ::testing::_));
}

void MockFidoDevice::SetDeviceTransport(
    FidoTransportProtocol transport_protocol) {
  transport_protocol_ = transport_protocol;
}

}  // namespace device
