// 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/card_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 <brillo/array_utils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

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

//
// General testing structure
// -------------------------
// The CardQrtr 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 CardQrtrTest testing framework.
//
// For each TEST_F(CardQrtrTest, ...) test, sending data from modem -> CardQrtr
// can be faked with CardQrtrTest::CardReceiveData(...). The CardQrtr -> modem
// messages are obviously not faked, as it is what we are testing, but
// CardQrtr::SendApdus is now wrapped by CardQrtrTest::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 CardQrtr::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 kTestPort = 59;
const char* kQrtrFilename = "/tmp/hermes_qrtr_test";

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

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 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
);

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

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());
  result[5] = result.size() - 7;
  result[12] = result.size() - 18;
  result[14] = std::distance(first, last) + 5;
  result[20] = std::distance(first, last);
  return result;
}

}  // namespace

// Expect CardQrtr instance to send the provided vector of data to the modem.
// This macro should only be called within a CardQrtrTest.
//
// Note that the transaction ID in the provided vector will be ignored and the
// earliest unused ID from CardQrtr::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 {

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

  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, CardQrtrTest 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 CardQrtr receiving data (" << size
              << " bytes): " << base::HexEncode(buf, size);

    if (metadata) {
      auto data = reinterpret_cast<SocketQrtr::PacketMetadata*>(metadata);
      data->node = kTestNode;
      if (size && *static_cast<uint8_t*>(buf) == QRTR_TYPE_NEW_SERVER) {
        data->port = QRTR_PORT_CTRL;
      } else {
        data->port = kTestPort;
      }
    }
    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 CardQrtrTest;

  base::ScopedFD socket_;
  DataAvailableCallback cb_;
};

// Test framework for CardQrtr tests. Allows for the faking of modem -> cpu
// responses with the use of CardReceiveData.
class CardQrtrTest : 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();
    card_ = CardQrtr::Create(std::move(socket), nullptr, nullptr);
    ASSERT_NE(card_, nullptr);

    receive_ids_.clear();
  }

  void TearDown() override {
    EXPECT_CALL(*socket_, Close());
    card_.reset(nullptr);
    fd_.reset();
  }

  // Wrapper for CardQrtr::SendApdus. Tests should use this rather than
  // CardQrtr::SendApdus.
  void SendApdus(std::vector<lpa::card::Apdu> commands,
                 CardQrtr::ResponseCallback cb) {
    EXPECT_CALL(*socket_, StartService(_, _, _))
        // Add a receive transaction id when new_lookup is called.
        .WillOnce(WithoutArgs(Invoke([this]() {
          this->receive_ids_.push_back(0);
          return true;
        })));

    {
      ::testing::InSequence dummy;

      // Expect RESET and OPEN_LOGICAL_CHANNEL request after receiving
      // NEW_SERVER.
      EXPECT_SEND(*socket_, kQrtrResetReq);
      EXPECT_SEND(*socket_, kQrtrOpenLogicalChannelReq);
    }

    card_->SendApdus(std::move(commands), std::move(cb));
    SimulateInitialization();

    EXPECT_CALL(*socket_, StopService(_, _, _));
  }

  // Cause |card_| to receive the provided data.
  template <typename Iterator>
  EnableIfIterator_t<Iterator, void> CardReceiveData(Iterator first,
                                                     Iterator last) {
    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 card buffer size so that the proper amount of data is read from fd.
    card_->buffer_.resize(receive_data.size());
    socket_->cb_.Run(card_->socket_.get());
  }

  void SimulateInitialization() {
    // Receive NEW_SERVER response from sock_new_lookup
    CardReceiveData(kQrtrNewServerResp.begin(), kQrtrNewServerResp.end());
    // Receive RESET response from RESET request
    CardReceiveData(kQrtrResetResp.begin(), kQrtrResetResp.end());
    // Receive repsonse to OPEN_LOGICAL_CHANNEL request
    CardReceiveData(kQrtrOpenLogicalChannelResp.begin(),
                    kQrtrOpenLogicalChannelResp.end());
  }

  base::ScopedFD fd_;
  // Queue of transaction ids created by the CardQrtr 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_;
  std::unique_ptr<CardQrtr> card_;
};

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

TEST_F(CardQrtrTest, EmptyApdu) {
  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);
}

TEST_F(CardQrtrTest, RequestGetEid) {
  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);
}

TEST_F(CardQrtrTest, SendTwoApdus) {
  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);
  CardReceiveData(kGetChallengeResp.begin(), kGetChallengeResp.end());
}

}  // namespace hermes
