/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include <openssl/evp.h>

#include "build_verity_tree_utils.h"
#include "verity/hash_tree_builder.h"

// The hex string we are using in build_image.py
// aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7
constexpr unsigned char kSaltHex[] = {
    0xae, 0xe0, 0x87, 0xa5, 0xbe, 0x3b, 0x98, 0x29, 0x78, 0xc9, 0x23,
    0xf5, 0x66, 0xa9, 0x46, 0x13, 0x49, 0x6b, 0x41, 0x7f, 0x2a, 0xf5,
    0x92, 0x63, 0x9b, 0xc8, 0x0d, 0x14, 0x1e, 0x34, 0xdf, 0xe7};

class BuildVerityTreeTest : public ::testing::Test {
 protected:
  void SetUp() override {
    salt_hex =
        std::vector<unsigned char>(kSaltHex, kSaltHex + sizeof(kSaltHex));
    builder.reset(new HashTreeBuilder(4096, EVP_sha256()));
  }

  const std::vector<unsigned char>& zero_block_hash() const {
    return builder->zero_block_hash_;
  }
  const std::vector<std::vector<unsigned char>>& verity_tree() const {
    return builder->verity_tree_;
  }

  void GenerateHashTree(const std::vector<unsigned char>& data,
                        const std::vector<unsigned char>& salt) {
    ASSERT_TRUE(builder->Initialize(data.size(), salt));
    ASSERT_TRUE(builder->Update(data.data(), data.size()));
    ASSERT_TRUE(builder->BuildHashTree());
  }

  std::vector<unsigned char> salt_hex;
  std::unique_ptr<HashTreeBuilder> builder;
};

TEST_F(BuildVerityTreeTest, CalculateSize) {
  // The hash of source data will occupy at least one block
  ASSERT_EQ(4096u, builder->CalculateSize(1));
  // Sha256 hash of 128 blocks fits into one block.
  ASSERT_EQ(4096u, builder->CalculateSize(128 * 4096));
  // Requires 3 blocks to hold more data.
  ASSERT_EQ(12288u, builder->CalculateSize(128 * 4096 + 1));

  ASSERT_EQ(20811776u, builder->CalculateSize(2641915904));
}

TEST_F(BuildVerityTreeTest, InitializeBuilder) {
  // data_size should be divisible by 4096
  ASSERT_FALSE(builder->Initialize(4095, salt_hex));

  ASSERT_TRUE(builder->Initialize(4096, salt_hex));
  ASSERT_EQ(1u, verity_tree().size());
  ASSERT_EQ("6eb8c4e1bce842d137f18b27beb857d3b43899d178090537ad7a0fbe3bf4126a",
            HashTreeBuilder::BytesArrayToString(zero_block_hash()));
}

TEST_F(BuildVerityTreeTest, HashSingleBlock) {
  std::vector<unsigned char> data(4096, 1);

  GenerateHashTree(data, salt_hex);

  ASSERT_EQ(1u, verity_tree().size());
  ASSERT_EQ("e69eb527b16f933483768e92de9bca45f6cc09208525d408436bb362eb865d32",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}

TEST_F(BuildVerityTreeTest, HashSingleLevel) {
  std::vector<unsigned char> data(128 * 4096, 0);

  GenerateHashTree(data, salt_hex);

  ASSERT_EQ(1u, verity_tree().size());
  ASSERT_EQ("62a4fbe8c9036168ba77fe3e3fd78dd6ed963aeb8aaaa36e84f5c7f9107c6b78",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}

TEST_F(BuildVerityTreeTest, HashMultipleLevels) {
  std::vector<unsigned char> data(129 * 4096, 0xff);

  GenerateHashTree(data, salt_hex);

  ASSERT_EQ(2u, verity_tree().size());
  ASSERT_EQ(2 * 4096u, verity_tree()[0].size());
  ASSERT_EQ("9e74f2d47a990c276093760f01de5e9039883e808286ee9492c9cafe9e4ff825",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}

TEST_F(BuildVerityTreeTest, StreamingDataMultipleBlocks) {
  std::vector<unsigned char> data(256 * 4096);
  for (size_t i = 0; i < 256; i++) {
    std::fill_n(data.begin() + i * 4096, 4096, i);
  }

  ASSERT_TRUE(builder->Initialize(data.size(), salt_hex));

  size_t offset = 0;
  while (offset < data.size()) {
    size_t data_length =
        std::min<size_t>(rand() % 10 * 4096, data.size() - offset);
    ASSERT_TRUE(builder->Update(data.data() + offset, data_length));
    offset += data_length;
  }

  ASSERT_TRUE(builder->BuildHashTree());
  ASSERT_EQ(2u, verity_tree().size());
  ASSERT_EQ(2 * 4096u, verity_tree()[0].size());
  ASSERT_EQ("6e73d59b0b6baf026e921814979a7db02244c95a46b869a17aa1310dad066deb",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}

TEST_F(BuildVerityTreeTest, StreamingDataPartialBlocks) {
  std::vector<unsigned char> data(256 * 4096);
  for (size_t i = 0; i < 256; i++) {
    std::fill_n(data.begin() + i * 4096, 4096, i);
  }

  ASSERT_TRUE(builder->Initialize(data.size(), salt_hex));

  size_t offset = 0;
  while (offset < data.size()) {
    size_t data_length = std::min<size_t>(rand() % 40960, data.size() - offset);
    ASSERT_TRUE(builder->Update(data.data() + offset, data_length));
    offset += data_length;
  }

  ASSERT_TRUE(builder->BuildHashTree());
  ASSERT_EQ(2u, verity_tree().size());
  ASSERT_EQ(2 * 4096u, verity_tree()[0].size());
  ASSERT_EQ("6e73d59b0b6baf026e921814979a7db02244c95a46b869a17aa1310dad066deb",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}

TEST_F(BuildVerityTreeTest, SHA1MultipleBlocks) {
  std::vector<unsigned char> data(128 * 4096, 0xff);

  builder.reset(
      new HashTreeBuilder(4096, HashTreeBuilder::HashFunction("SHA1")));

  GenerateHashTree(data, salt_hex);
  ASSERT_EQ(1u, verity_tree().size());
  ASSERT_EQ("7ea287e6167929988810077abaafbc313b2b8593000000000000000000000000",
            HashTreeBuilder::BytesArrayToString(builder->root_hash()));
}
