// Copyright 2014 The Chromium 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 "base/base64.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "crypto/sha2.h"
#include "extensions/browser/computed_hashes.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Helper to return base64 encode result by value.
std::string Base64Encode(const std::string& data) {
  std::string result;
  base::Base64Encode(data, &result);
  return result;
}

}  // namespace

namespace extensions {

TEST(ComputedHashes, ComputedHashes) {
  base::ScopedTempDir scoped_dir;
  ASSERT_TRUE(scoped_dir.CreateUniqueTempDir());
  base::FilePath computed_hashes =
      scoped_dir.GetPath().AppendASCII("computed_hashes.json");

  // We'll add hashes for 2 files, one of which uses a subdirectory
  // path. The first file will have a list of 1 block hash, and the
  // second file will have 2 block hashes.
  base::FilePath path1(FILE_PATH_LITERAL("foo.txt"));
  base::FilePath path2 =
      base::FilePath(FILE_PATH_LITERAL("foo")).AppendASCII("bar.txt");
  std::vector<std::string> hashes1;
  std::vector<std::string> hashes2;
  hashes1.push_back(crypto::SHA256HashString("first"));
  hashes2.push_back(crypto::SHA256HashString("second"));
  hashes2.push_back(crypto::SHA256HashString("third"));

  // Write them into the file.
  ComputedHashes::Writer writer;
  writer.AddHashes(path1, 4096, hashes1);
  writer.AddHashes(path2, 2048, hashes2);
  EXPECT_TRUE(writer.WriteToFile(computed_hashes));

  // Now read them back again and assert that we got what we wrote.
  ComputedHashes::Reader reader;
  std::vector<std::string> read_hashes1;
  std::vector<std::string> read_hashes2;
  EXPECT_TRUE(reader.InitFromFile(computed_hashes));

  int block_size = 0;
  EXPECT_TRUE(reader.GetHashes(path1, &block_size, &read_hashes1));
  EXPECT_EQ(block_size, 4096);
  block_size = 0;
  EXPECT_TRUE(reader.GetHashes(path2, &block_size, &read_hashes2));
  EXPECT_EQ(block_size, 2048);

  EXPECT_EQ(hashes1, read_hashes1);
  EXPECT_EQ(hashes2, read_hashes2);

  // Make sure we can lookup hashes for a file using incorrect case
  base::FilePath path1_badcase(FILE_PATH_LITERAL("FoO.txt"));
  std::vector<std::string> read_hashes1_badcase;
  EXPECT_TRUE(
      reader.GetHashes(path1_badcase, &block_size, &read_hashes1_badcase));
  EXPECT_EQ(block_size, 4096);
  EXPECT_EQ(hashes1, read_hashes1_badcase);

  // Finally make sure that we can retrieve the hashes for the subdir
  // path even when that path contains forward slashes (on windows).
  base::FilePath path2_fwd_slashes =
      base::FilePath::FromUTF8Unsafe("foo/bar.txt");
  block_size = 0;
  EXPECT_TRUE(reader.GetHashes(path2_fwd_slashes, &block_size, &read_hashes2));
  EXPECT_EQ(hashes2, read_hashes2);
}

// Note: the expected hashes used in this test were generated using linux
// command line tools. E.g., from a bash prompt:
//  $ printf "hello world" | openssl dgst -sha256 -binary | base64
//
// The file with multiple-blocks expectations were generated by doing:
// $ for i in `seq 500 ; do printf "hello world" ; done > hello.txt
// $ dd if=hello.txt bs=4096 count=1 | openssl dgst -sha256 -binary | base64
// $ dd if=hello.txt skip=1 bs=4096 count=1 |
//   openssl dgst -sha256 -binary | base64
TEST(ComputedHashes, ComputeHashesForContent) {
  const int block_size = 4096;

  // Simple short input.
  std::string content1 = "hello world";
  std::string content1_expected_hash =
      "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=";
  std::vector<std::string> hashes1;
  ComputedHashes::ComputeHashesForContent(content1, block_size, &hashes1);
  ASSERT_EQ(1u, hashes1.size());
  EXPECT_EQ(content1_expected_hash, Base64Encode(hashes1[0]));

  // Multiple blocks input.
  std::string content2;
  for (int i = 0; i < 500; i++)
    content2 += "hello world";
  const char* content2_expected_hashes[] = {
      "bvtt5hXo8xvHrlzGAhhoqPL/r+4zJXHx+6wAvkv15V8=",
      "lTD45F7P6I/HOdi8u7FLRA4qzAYL+7xSNVeusG6MJI0="};
  std::vector<std::string> hashes2;
  ComputedHashes::ComputeHashesForContent(content2, block_size, &hashes2);
  ASSERT_EQ(2u, hashes2.size());
  EXPECT_EQ(content2_expected_hashes[0], Base64Encode(hashes2[0]));
  EXPECT_EQ(content2_expected_hashes[1], Base64Encode(hashes2[1]));

  // Now an empty input.
  std::string content3;
  std::vector<std::string> hashes3;
  ComputedHashes::ComputeHashesForContent(content3, block_size, &hashes3);
  ASSERT_EQ(1u, hashes3.size());
  ASSERT_EQ(std::string("47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="),
            Base64Encode(hashes3[0]));
}

}  // namespace extensions
