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

#include <cstdint>
#include <type_traits>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::_;
using ::testing::ElementsAreArray;

namespace hermes {

// The ToVector functions create a single vector<uint8_t> given a list of
// integers and vector<uint8_t>s of any amount.
std::vector<uint8_t> ToVector() {
  return std::vector<uint8_t>();
}

template<typename T>
std::vector<uint8_t> ToVector(T v) {
  return std::vector<uint8_t>{static_cast<uint8_t>(v)};
}

std::vector<uint8_t> ToVector(std::vector<uint8_t> v) {
  return v;
}

template<typename T, typename... Args>
std::vector<uint8_t> ToVector(T&& first, Args&&... args) {
  std::vector<uint8_t> head = ToVector(std::forward<T>(first));
  std::vector<uint8_t> tail = ToVector(std::forward<Args>(args)...);
  head.insert(head.end(), tail.begin(), tail.end());
  return head;
}

// Expect the value of the next fragment.
//
// The first parameter is the CommandApdu. Futher parameters can be any number
// of integers (which will all be cast to uint8_ts) and vector<uint8_t>s, in
// any order.
//
// Note that by making EXPECT_FRAGMENT a macro, failures will report the actual
// line number within the test that caused the failure. If this were a function,
// failures would point to the line number within EXPECT_FRAGMENT, which is much
// less informative.
#define EXPECT_FRAGMENT(apdu, ...)                                      \
  do {                                                                  \
    uint8_t* fragment;                                                  \
    size_t fragment_len = apdu.GetNextFragment(&fragment);              \
    EXPECT_NE(fragment, nullptr);                                       \
    EXPECT_THAT(std::vector<uint8_t>(fragment, fragment+fragment_len),  \
                ElementsAreArray(ToVector(__VA_ARGS__)));               \
  } while (0)

///////////////
// Constants //
///////////////

const std::vector<uint8_t> kHeaderStart =
  ToVector(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA);

constexpr uint16_t kShortLe = 18;
constexpr uint16_t kLongLe = 1800;

//////////////////////////
// Command APDU: Case 1 //
//////////////////////////

TEST(CommandCase1, Standard) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, 0);
  EXPECT_FRAGMENT(cmd, kHeaderStart, kApduP1LastBlock, 0);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase1, Extended) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, 0);
  EXPECT_FRAGMENT(cmd, kHeaderStart, kApduP1LastBlock, 0);
  EXPECT_FRAGMENT(cmd);
}

//////////////////////////
// Command APDU: Case 2 //
//////////////////////////

TEST(CommandCase2, StandardWithShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kShortLe);
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 0,
                  static_cast<uint8_t>(kShortLe));
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase2, StandardWithLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kLongLe);
  // Le field should be set to 0 (Ne=256)
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 0, 0);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase2, ExtendedWithShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kShortLe);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  // Extended Le field
                  0, static_cast<uint8_t>(kShortLe), 0);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase2, ExtendedWithLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kLongLe);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  // Extended Le field
                  0, static_cast<uint8_t>(kLongLe),
                  static_cast<uint8_t>(kLongLe >> 8));
  EXPECT_FRAGMENT(cmd);
}

//////////////////////////
// Command APDU: Case 3 //
//////////////////////////

TEST(CommandCase3, StandardNoFragment) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, 0);
  std::vector<uint8_t> data = ToVector(1, 2, 3);
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 0,
                  data.size(), data);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase3, StandardTwoFragments) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, 0);
  std::vector<uint8_t> data;
  for (int i = 0; i < 300; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  // Data should be fragmented between 255 and 45 bytes
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  255, std::vector<uint8_t>(data.begin(), data.begin() + 255));
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 1,
                  45, std::vector<uint8_t>(data.begin() + 255, data.end()));
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase3, ExtendedNoFragmentShort) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, 0);
  std::vector<uint8_t> data = ToVector(1, 2, 3);
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  0, data.size(), 0, data);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase3, ExtendedNoFragmentLong) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, 0);
  size_t data_len = 20000;
  std::vector<uint8_t> data;
  for (size_t i = 0; i < data_len; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  0, data_len & 0xFF, data_len >> 8, data);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase3, ExtendedTwoFragments) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, 0);
  size_t data_len = 40000;
  std::vector<uint8_t> data;
  for (size_t i = 0; i < data_len; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  size_t frag_len = 32767;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin(), data.begin() + frag_len));
  frag_len = data_len - frag_len;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 1,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin() + 32767, data.end()));
  EXPECT_FRAGMENT(cmd);
}

//////////////////////////
// Command APDU: Case 4 //
//////////////////////////

TEST(CommandCase4, StandardNoFragmentShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kShortLe);
  std::vector<uint8_t> data = ToVector(1, 2, 3);
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 0,
                  data.size(), data,
                  kShortLe);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, StandardTwoFragmentsShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kShortLe);
  std::vector<uint8_t> data;
  for (int i = 0; i < 300; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  // Data should be fragmented between 255 and 45 bytes with no Le in the first
  // fragment
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  255, std::vector<uint8_t>(data.begin(), data.begin() + 255));
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 1,
                  45, std::vector<uint8_t>(data.begin() + 255, data.end()),
                  kShortLe);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, StandardNoFragmentLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kLongLe);
  std::vector<uint8_t> data = ToVector(1, 2, 3);
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 0,
                  data.size(), data,
                  256);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, StandardTwoFragmentsLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  false, kLongLe);
  std::vector<uint8_t> data;
  for (int i = 0; i < 300; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  // Data should be fragmented between 255 and 45 bytes with no Le in the first
  // fragment
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  255, std::vector<uint8_t>(data.begin(), data.begin() + 255));
  EXPECT_FRAGMENT(cmd,
                  kHeaderStart, kApduP1LastBlock, 1,
                  45, std::vector<uint8_t>(data.begin() + 255, data.end()),
                  256);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, ExtendedNoFragmentShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kShortLe);
  std::vector<uint8_t> data = ToVector(1, 2, 3);
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  0, data.size(), 0, data,
                  0, kShortLe, 0);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, ExtendedNoFragmentLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kLongLe);
  size_t data_len = 20000;
  std::vector<uint8_t> data;
  for (size_t i = 0; i < data_len; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 0,
                  0, data_len & 0xFF, data_len >> 8, data,
                  0, kLongLe & 0xFF, kLongLe >> 8);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, ExtendedTwoFragmentsShortLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kShortLe);
  size_t data_len = 40000;
  std::vector<uint8_t> data;
  for (size_t i = 0; i < data_len; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  size_t frag_len = 32767;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin(), data.begin() + frag_len));
  frag_len = data_len - frag_len;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 1,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin() + 32767, data.end()),
                  0, kShortLe, 0);
  EXPECT_FRAGMENT(cmd);
}

TEST(CommandCase4, ExtendedTwoFragmentsLongLe) {
  CommandApdu cmd(ApduClass::STORE_DATA, ApduInstruction::STORE_DATA,
                  true, kLongLe);
  size_t data_len = 40000;
  std::vector<uint8_t> data;
  for (size_t i = 0; i < data_len; ++i) {
    data.push_back(static_cast<uint8_t>(i));
  }
  cmd.AddData(data);
  size_t frag_len = 32767;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1MoreBlocks, 0,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin(), data.begin() + frag_len));
  frag_len = data_len - frag_len;
  EXPECT_FRAGMENT(cmd,
                  // Header
                  kHeaderStart, kApduP1LastBlock, 1,
                  0, frag_len & 0xFF, frag_len >> 8,
                  std::vector<uint8_t>(data.begin() + 32767, data.end()),
                  0, kLongLe & 0xFF, kLongLe >> 8);
  EXPECT_FRAGMENT(cmd);
}

}  // namespace hermes
