// 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_;
};

// Extend ModemManagerProxy to use it's protected constructor.
class FakeModemManagerProxy : public ModemManagerProxy {};

// 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();
    auto modem_manager_proxy = std::make_unique<FakeModemManagerProxy>();
    modem_ = ModemQrtr::Create(std::move(socket), nullptr, &executor_,
                               std::move(modem_manager_proxy));
    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 in_seq;

      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, ResultCallback());
  }

  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_, ResultCallback());
    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 in_seq;
      // Expect RESET and GET_SLOTS request after
      // receiving UIM NEW_SERVER.
      EXPECT_SEND(*socket_, kQrtrGetSlotsReq);
      EXPECT_SEND(*socket_, kQrtrResetReq);
    }
    ModemReceiveData(kQrtrNewUimServerResp.begin(), kQrtrNewUimServerResp.end(),
                     QRTR_PORT_CTRL);
    // Receive slot info from GET_SLOTS request.
    ModemReceiveData(kQrtrGetSlotsResp.begin(), kQrtrGetSlotsResp.end(),
                     kUimPort);
    // Receive RESET response from RESET request.
    ModemReceiveData(kQrtrResetResp.begin(), kQrtrResetResp.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 in_seq;

    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
