// Copyright 2018 The Chromium OS 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 "hermes/modem_qrtr.h"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/test/test_mock_time_task_runner.h>
#include <brillo/array_utils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "hermes/apdu.h"
#include "hermes/fake_euicc_manager.h"
#include "hermes/sgp_22.h"
#include "hermes/socket_qrtr.h"
#include "hermes/type_traits.h"

//
// General testing structure
// -------------------------
// The ModemQrtr implementation sends and receives data from a qrtr socket,
// whose other end is a modem. In order to fake communication with the modem,
// the qrtr socket is replaced with a regular file descriptor, with the modem
// itself being faked by the ModemQrtrTest testing framework.
//
// For each TEST_F(ModemQrtrTest, ...) test, sending data from modem ->
// ModemQrtr can be faked with ModemQrtrTest::ModemReceiveData(...). The
// ModemQrtr -> modem messages are obviously not faked, as it is what we are
// testing, but ModemQrtr::SendApdus is now wrapped by ModemQrtrTest::SendApdus.
// The EXPECT_SEND macro is used to verify that the sent data is as we expected.
// In both cases, the transaction IDs of provided data is ignored, and the
// proper transaction ID values from the calls made to ModemQrtr::AllocateIds
// are used instead. This means that tests will not break if the implementation
// of AllocateIds is changed.
//

using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::Invoke;
using ::testing::WithArgs;
using ::testing::WithoutArgs;

namespace {

constexpr uint32_t kTestNode = 0;
constexpr uint32_t kUimPort = 49;
constexpr uint32_t kDmsPort = 56;
const char* kQrtrFilename = "/tmp/hermes_qrtr_test";

// clang-format off
constexpr auto kQrtrNewUimServerResp = brillo::make_array<uint8_t>(
  0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00
);

constexpr auto kQrtrNewDmsServerResp = brillo::make_array<uint8_t>(
  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
);

constexpr auto kQrtrGetSerialNumbersReq = brillo::make_array<uint8_t>(
  0x00, 0x01, 0x00, 0x25, 0x00, 0x00, 0x00
);

constexpr auto kQrtrGetSerialNumbersResp = brillo::make_array<uint8_t>(
  0x02, 0x01, 0x00, 0x25, 0x00, 0x1D, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x10, 0x01, 0x00, 0x30, 0x11, 0x0F, 0x00, 0x30, 0x31, 0x35, 0x37, 0x36,
  0x39, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x37, 0x38, 0x36
);

constexpr auto kQrtrResetReq = brillo::make_array<uint8_t>(
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
);

constexpr auto kQrtrResetResp = brillo::make_array<uint8_t>(
  0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00
);

constexpr auto kQrtrGetSlotsReq = brillo::make_array<uint8_t>(
    0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00
);

// 2 eUICC's present, Slot 2 active
constexpr auto kQrtrGetSlotsResp = brillo::make_array<uint8_t>(
  0x02, 0x01, 0x00, 0x47, 0x00, 0x8F, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x12, 0x23, 0x00, 0x02, 0x10, 0x89, 0x03, 0x30, 0x23, 0x42, 0x51, 0x20,
  0x00, 0x00, 0x00, 0x00, 0x09, 0x71, 0x04, 0x17, 0x04, 0x10, 0x89, 0x03, 0x30,
  0x23, 0x42, 0x51, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x64, 0x68, 0x11,
  0x13, 0x05, 0x00, 0x02, 0x01, 0x00, 0x01, 0x00, 0x11, 0x3F, 0x00, 0x02, 0x02,
  0x00, 0x00, 0x00, 0x00, 0x18, 0x3B, 0x9F, 0x97, 0xC0, 0x0A, 0x3F, 0xC6, 0x82,
  0x80, 0x31, 0xE0, 0x73, 0xFE, 0x21, 0x1B, 0x65, 0xD0, 0x02, 0x33, 0x14, 0xA5,
  0x81, 0x0F, 0xE4, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3B, 0x9F, 0x97,
  0xC0, 0x0A, 0x3F, 0xC6, 0x82, 0x80, 0x31, 0xE0, 0x73, 0xFE, 0x21, 0x1B, 0x65,
  0xD0, 0x02, 0x33, 0x14, 0xA5, 0x81, 0x0F, 0xE4, 0x01, 0x10, 0x15, 0x00, 0x02,
  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00,
  0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00
);

// Switch to slot 1
constexpr auto kQrtrSwitchSlotReq = brillo::make_array<uint8_t>(
  0x00, 0x07, 0x00, 0x46, 0x00, 0x0B, 0x00, 0x01, 0x01, 0x00, 0x01, 0x02, 0x04,
  0x00, 0x01, 0x00, 0x00, 0x00
);

constexpr auto kQrtrSwitchSlotResp = brillo::make_array<uint8_t>(
  0x02, 0x07, 0x00, 0x46, 0x00, 0x07, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00
);

constexpr auto kQrtrOpenLogicalChannelReq = brillo::make_array<uint8_t>(
  0x00, 0x00, 0x00, 0x42, 0x00, 0x18, 0x00, 0x01, 0x01, 0x00, 0x01, 0x10, 0x11,
  0x00, 0x10, 0xA0, 0x00, 0x00, 0x05, 0x59, 0x10, 0x10, 0xFF, 0xFF, 0xFF, 0xFF,
  0x89, 0x00, 0x00, 0x01, 0x00
);

constexpr auto kQrtrOpenLogicalChannelResp = brillo::make_array<uint8_t>(
  0x02, 0x00, 0x00, 0x42, 0x00, 0x35, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x12, 0x22, 0x00, 0x21, 0x6F, 0x1F, 0x84, 0x10, 0xA0, 0x00, 0x00, 0x05,
  0x59, 0x10, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x89, 0x00, 0x00, 0x01, 0x00, 0xA5,
  0x04, 0x9F, 0x65, 0x01, 0xFF, 0xE0, 0x05, 0x82, 0x03, 0x02, 0x00, 0x00, 0x11,
  0x02, 0x00, 0x90, 0x00, 0x10, 0x01, 0x00, 0x01
);

constexpr auto kApduPrefix = brillo::make_array<uint8_t>(
  0x00, 0x00, 0x00, 0x3B, 0x00, 0x13, 0x00, 0x01, 0x01, 0x00, 0x01, 0x02, 0x08,
  0x00, 0x06, 0x00, 0x80, 0xE2, 0x91, 0x00, 0x00
);

// kApduSuffix consists of channel_id and procedure_bytes_tlvs
constexpr auto kApduSuffix = brillo::make_array<uint8_t>(
  0x10, 0x01, 0x00, 0x01, 0x11, 0x01, 0x00, 0x00
);

constexpr auto kGetChallengeApdu = brillo::make_array<uint8_t>(
  0xBF, 0x2E, 0x00
);

constexpr auto kGetChallengeResp = brillo::make_array<uint8_t>(
  0x02, 0x00, 0x00, 0x3B, 0x00, 0x23, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x10, 0x19, 0x00, 0x17, 0x00, 0xBF, 0x2E, 0x12, 0x80, 0x10, 0x5A, 0x6C,
  0x23, 0x71, 0x94, 0xBE, 0xAB, 0x24, 0xF4, 0xEF, 0xAB, 0x54, 0xB7, 0x3A, 0x59,
  0xCF, 0x90, 0x00
);
// clang-format on

void NullResponseCallback(
    std::vector<std::vector<uint8_t>>& responses,  // NOLINT(runtime/references)
    int err) {}

// Create a full QRTR packet given the data of an APDU message. The current
// implementation only works for non-fragmented APDUs.
template <typename Iterator>
hermes::EnableIfIterator_t<Iterator, std::vector<uint8_t>> CreateQrtrFromApdu(
    Iterator first, Iterator last) {
  std::vector<uint8_t> result;
  result.insert(result.end(), kApduPrefix.begin(), kApduPrefix.end());
  result.insert(result.end(), first, last);
  result.insert(result.end(), kApduSuffix.begin(), kApduSuffix.end());
  constexpr int kControlBytesSize = 1;
  constexpr int kTxnIdSize = 2;
  constexpr int kMsgIdSize = 2;
  constexpr int kMsgLenSize = 2;
  constexpr int kMsgLenIndex = kControlBytesSize + kTxnIdSize +
                               kMsgIdSize;  // Length of the QMI message sans
                                            // header is stored at this index
  constexpr int kQmiHeaderSize =
      kControlBytesSize + kTxnIdSize + kMsgIdSize + kMsgLenSize;
  result[kMsgLenIndex] = result.size() - kQmiHeaderSize;

  constexpr int kApduLenIndex = 14;   // Length of APDU is stored at this index
  constexpr int kApduLenSize = 2;     // 2 bytes to store the length of the APDU
  constexpr int kApduHeaderSize = 5;  // CLA + INS + P1 +P2 + Lc
  result[kApduLenIndex] =
      std::distance(first, last) +
      kApduHeaderSize;  // len(CLA + INS + P1 +P2 + Lc + CMD_DATA)
  constexpr int kLcIndex = 20;
  result[kLcIndex] = std::distance(first, last);  // Lc = len(CMD_DATA)

  constexpr int kApduTlvLenIndex =
      12;  // Length of TLV with tag=0x02 is stored at this index.
  result[kApduTlvLenIndex] =
      result[kApduLenIndex] +
      kApduLenSize;  // length of TLV with tag=0x02 is length(APDU) + (2 bytes
                     // that store length(APDU))

  return result;
}

}  // namespace

// Expect ModemQrtr instance to send the provided vector of data to the modem.
// This macro should only be called within a ModemQrtrTest.
//
// Note that the transaction ID in the provided vector will be ignored and the
// earliest unused ID from ModemQrtr::AllocateId will be used instead. This
// allows for changes in message ordering to not invalidate the data passed
// to this macro.
#define EXPECT_SEND(socket_obj, data)                                         \
  EXPECT_CALL(socket_obj, Send(_, data.size(), _))                            \
      .Times(1)                                                               \
      .WillOnce(                                                              \
          WithArgs<0, 1>(Invoke([this, d = data](const void* arr, size_t l) { \
            const uint8_t* array = reinterpret_cast<const uint8_t*>(arr);     \
            auto expected = d;                                                \
            expected[1] = array[1];                                           \
            this->receive_ids_.push_back(expected[1]);                        \
            EXPECT_THAT(expected, ElementsAreArray(array, l));                \
            return 0;                                                         \
          })))

namespace hermes {

class MockExecutor : public Executor {
 public:
  MockExecutor() : Executor(new base::TestMockTimeTaskRunner()) {}
  void FastForwardBy(base::TimeDelta duration) {
    scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_(
        dynamic_cast<base::TestMockTimeTaskRunner*>(task_runner().get()));
    mock_task_runner_->FastForwardBy(duration);
  }
};

// Socket class which mocks the outgoing (host -> modem) socket calls and
// provides implementations for incoming (modem -> host) socket calls that reads
// data from kQrtrFilename rather than from an actual QRTR socket.
class MockSocketQrtr : public SocketInterface {
 public:
  void SetDataAvailableCallback(DataAvailableCallback cb) override { cb_ = cb; }
  void SetPort(uint32_t port) { port_ = port; }

  bool Open() override {
    socket_ = base::ScopedFD(open(kQrtrFilename, O_RDWR));
    if (!socket_.is_valid()) {
      return false;
    }
    int off = lseek(socket_.get(), 0, SEEK_SET);
    EXPECT_EQ(off, 0);
    // Return without setting up a MessageLoop::WatchFileDescriptor. The epoll
    // syscall does not always support regular file descriptors. Libevent could
    // be configured not to use epoll, but this would require modifying or
    // substituting base::MessagePumpLibevent. Instead, ModemQrtrTest will
    // manually call the DataAvailableCallback as needed.
    return true;
  }

  bool IsValid() const override { return socket_.is_valid(); }
  Type GetType() const override { return Type::kQrtr; }

  int Recv(void* buf, size_t size, void* metadata) override {
    int bytes_read = read(socket_.get(), buf, size);
    EXPECT_EQ(bytes_read, size);
    LOG(INFO) << "Mock ModemQrtr receiving data (" << size
              << " bytes): " << base::HexEncode(buf, size);

    if (metadata) {
      auto data = reinterpret_cast<SocketQrtr::PacketMetadata*>(metadata);
      data->node = kTestNode;
      data->port = port_;
    }
    return bytes_read;
  }

  MOCK_METHOD(void, Close, (), (override));
  MOCK_METHOD(bool, StartService, (uint32_t, uint16_t, uint16_t), (override));
  MOCK_METHOD(bool, StopService, (uint32_t, uint16_t, uint16_t), (override));
  MOCK_METHOD(int, Send, (const void*, size_t, const void*), (override));

 private:
  friend class ModemQrtrTest;

  base::ScopedFD socket_;
  uint32_t port_;
  DataAvailableCallback cb_;
};

// Test framework for ModemQrtr tests. Allows for the faking of modem -> cpu
// responses with the use of ModemReceiveData.
class ModemQrtrTest : public testing::Test {
 protected:
  // Fake modem initialization such that tests may jump right to sending QMI
  // commands
  void SetUp() override {
    fd_.reset(open(kQrtrFilename, O_RDWR | O_CREAT | O_TRUNC, 0777));
    ASSERT_TRUE(fd_.is_valid());

    auto socket = std::make_unique<MockSocketQrtr>();
    socket_ = socket.get();
    modem_ = ModemQrtr::Create(std::move(socket), nullptr, &executor_);
    ASSERT_NE(modem_, nullptr);

    receive_ids_.clear();

    SimulateInitialization();
  }

  void TearDown() override {
    EXPECT_CALL(
        *socket_,
        StopService(to_underlying(QmiCmdInterface::Service::kDms), _, _));
    EXPECT_CALL(
        *socket_,
        StopService(to_underlying(QmiCmdInterface::Service::kUim), _, _));
    EXPECT_CALL(*socket_, Close());
    modem_.reset(nullptr);
    fd_.reset();
  }

  // Set's up expectations for messages that go out when a slot switch happens
  void InitSlot(uint8_t physical_slot) {
    {
      ::testing::InSequence dummy;

      EXPECT_SEND(*socket_, kQrtrGetSlotsReq);
      // Slot 2 is the active slot after test initialization. If slot 1 is
      // requested, a SwitchSlot message is expected
      if (physical_slot == 1)
        EXPECT_SEND(*socket_, kQrtrSwitchSlotReq);
      EXPECT_SEND(*socket_, kQrtrResetReq);
      EXPECT_SEND(*socket_, kQrtrOpenLogicalChannelReq);
    }
    modem_->StoreAndSetActiveSlot(physical_slot);
  }

  void ModemReceiveInitSlot(uint8_t physical_slot) {
    ModemReceiveData(kQrtrGetSlotsResp.begin(), kQrtrGetSlotsResp.end(),
                     kUimPort);
    if (physical_slot == 1) {
      ModemReceiveData(kQrtrSwitchSlotResp.begin(), kQrtrSwitchSlotResp.end(),
                       kUimPort);
      EXPECT_EQ(modem_->qmi_disabled_, true);
      executor_.FastForwardBy(ModemQrtr::kSwitchSlotDelay);
      EXPECT_EQ(modem_->qmi_disabled_, false);
    }
    ModemReceiveData(kQrtrResetResp.begin(), kQrtrResetResp.end(), kUimPort);
    ModemReceiveData(kQrtrOpenLogicalChannelResp.begin(),
                     kQrtrOpenLogicalChannelResp.end(), kUimPort);
  }

  // Wrapper for ModemQrtr::SendApdus. Tests should use this rather than
  // ModemQrtr::SendApdus.
  void SendApdus(std::vector<lpa::card::Apdu> commands,
                 ModemQrtr::ResponseCallback cb) {
    modem_->SendApdus(std::move(commands), std::move(cb));
  }

  // Cause |modem_| to receive the provided data.
  template <typename Iterator>
  EnableIfIterator_t<Iterator, void> ModemReceiveData(Iterator first,
                                                      Iterator last,
                                                      uint32_t port) {
    std::vector<uint8_t> receive_data(first, last);
    receive_data[1] = receive_ids_[0];
    receive_ids_.pop_front();

    int ret = write(fd_.get(), receive_data.data(), receive_data.size());
    EXPECT_EQ(ret, receive_data.size());
    // Set modem buffer size so that the proper amount of data is read from fd.
    modem_->buffer_.resize(receive_data.size());
    socket_->SetPort(port);
    socket_->cb_.Run(modem_->socket_.get());
  }

  void SimulateInitialization() {
    // Start DMS service and populate IMEI
    EXPECT_CALL(
        *socket_,
        StartService(to_underlying(QmiCmdInterface::Service::kDms), _, _))
        .WillOnce(WithoutArgs(Invoke([this]() {
          this->receive_ids_.push_back(0);
          return true;
        })));
    modem_->Initialize(&euicc_manager_);
    EXPECT_EQ(euicc_manager_.valid_slots().size(), 0);
    EXPECT_SEND(*socket_, kQrtrGetSerialNumbersReq);
    ModemReceiveData(kQrtrNewDmsServerResp.begin(), kQrtrNewDmsServerResp.end(),
                     QRTR_PORT_CTRL);

    EXPECT_CALL(
        *socket_,
        StartService(to_underlying(QmiCmdInterface::Service::kUim), _, _))
        .WillOnce(WithoutArgs(Invoke([this]() {
          this->receive_ids_.push_back(0);
          return true;
        })));
    ModemReceiveData(kQrtrGetSerialNumbersResp.begin(),
                     kQrtrGetSerialNumbersResp.end(), kDmsPort);

    {
      ::testing::InSequence dummy;
      // Expect RESET and GET_SLOTS request after
      // receiving UIM NEW_SERVER.
      EXPECT_SEND(*socket_, kQrtrResetReq);
      EXPECT_SEND(*socket_, kQrtrGetSlotsReq);
    }
    ModemReceiveData(kQrtrNewUimServerResp.begin(), kQrtrNewUimServerResp.end(),
                     QRTR_PORT_CTRL);
    // Receive RESET response from RESET request.
    ModemReceiveData(kQrtrResetResp.begin(), kQrtrResetResp.end(), kUimPort);
    // Receive slot info from GET_SLOTS request.
    ModemReceiveData(kQrtrGetSlotsResp.begin(), kQrtrGetSlotsResp.end(),
                     kUimPort);
    EXPECT_EQ(euicc_manager_.valid_slots().size(), 2);
    EXPECT_EQ(euicc_manager_.valid_slots().at(1),
              EuiccSlotInfo("89033023425120000000000971041704"));
    EXPECT_EQ(euicc_manager_.valid_slots().at(2),
              EuiccSlotInfo(1, "89033023425120000000000011646811"));
    EXPECT_EQ(1, modem_->logical_slot_);
  }

  base::ScopedFD fd_;
  // Queue of transaction ids created by the ModemQrtr instance in question.
  // This is used such that AllocateId implementations may change without
  // breaking the unit tests (which should not be affected by changes in id
  // allocation strategy).  Send ids are ids to use when sending commands.
  // Likewise for receive ids.
  std::deque<uint16_t> receive_ids_;
  MockSocketQrtr* socket_;
  MockExecutor executor_;
  std::unique_ptr<ModemQrtr> modem_;
  FakeEuiccManager euicc_manager_;
};

///////////
// TESTS //
///////////

// Sends an apdu on slot 2. Since Slot 2 is active by default, the following
// qmi messages are expected: GetSlots,Reset,OpenLogicalChannel,SendApdu
TEST_F(ModemQrtrTest, EmptyApduSlot2) {
  InitSlot(2);
  auto v = std::vector<uint8_t>();
  EXPECT_SEND(*socket_, CreateQrtrFromApdu(v.begin(), v.end()));
  std::vector<lpa::card::Apdu> commands = {lpa::card::Apdu::NewStoreData({})};
  SendApdus(std::move(commands), NullResponseCallback);
  ModemReceiveInitSlot(2);
}

// Sends an apdu on slot 1. Since Slot 1 is not active by default, the following
// qmi messages are expected: GetSlots, SwitchSlot, Reset, OpenLogicalChannel,
// and SendApdu
TEST_F(ModemQrtrTest, EmptyApduSlot1) {
  InitSlot(1);
  auto v = std::vector<uint8_t>();
  EXPECT_SEND(*socket_, CreateQrtrFromApdu(v.begin(), v.end()));
  std::vector<lpa::card::Apdu> commands = {lpa::card::Apdu::NewStoreData({})};
  SendApdus(std::move(commands), NullResponseCallback);
  ModemReceiveInitSlot(1);
}

TEST_F(ModemQrtrTest, RequestGetEid) {
  InitSlot(2);
  EXPECT_SEND(*socket_, CreateQrtrFromApdu(kGetChallengeApdu.begin(),
                                           kGetChallengeApdu.end()));
  std::vector<lpa::card::Apdu> commands = {
      lpa::card::Apdu::NewStoreData(std::vector<uint8_t>(
          kGetChallengeApdu.begin(), kGetChallengeApdu.end()))};
  SendApdus(std::move(commands), NullResponseCallback);
  ModemReceiveInitSlot(2);
}

TEST_F(ModemQrtrTest, SendTwoApdus) {
  InitSlot(2);
  auto v = std::vector<uint8_t>();
  {
    ::testing::InSequence dummy;

    EXPECT_SEND(*socket_, CreateQrtrFromApdu(kGetChallengeApdu.begin(),
                                             kGetChallengeApdu.end()));
    // Do not expect to reinitialize the modem in between APDUs.
    EXPECT_SEND(*socket_, CreateQrtrFromApdu(v.begin(), v.end()));
  }

  std::vector<lpa::card::Apdu> commands = {
      lpa::card::Apdu::NewStoreData(std::vector<uint8_t>(
          kGetChallengeApdu.begin(), kGetChallengeApdu.end())),
      lpa::card::Apdu::NewStoreData({})};
  SendApdus(std::move(commands), NullResponseCallback);
  ModemReceiveInitSlot(2);
  ModemReceiveData(kGetChallengeResp.begin(), kGetChallengeResp.end(),
                   kUimPort);
}

}  // namespace hermes
