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