// Copyright (c) 2012 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 "content/browser/download/base_file.h"

#include <stddef.h>
#include <stdint.h>
#include <utility>

#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/test_file_util.h"
#include "build/build_config.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

const char kTestData1[] = "Let's write some data to the file!\n";
const char kTestData2[] = "Writing more data.\n";
const char kTestData3[] = "Final line.";
const char kTestData4[] = "supercalifragilisticexpialidocious";
const int kTestDataLength1 = arraysize(kTestData1) - 1;
const int kTestDataLength2 = arraysize(kTestData2) - 1;
const int kTestDataLength3 = arraysize(kTestData3) - 1;
const int kTestDataLength4 = arraysize(kTestData4) - 1;

// SHA-256 hash of kTestData1 (excluding terminating NUL).
const uint8_t kHashOfTestData1[] = {
    0x0b, 0x2d, 0x3f, 0x3f, 0x79, 0x43, 0xad, 0x64, 0xb8, 0x60, 0xdf,
    0x94, 0xd0, 0x5c, 0xb5, 0x6a, 0x8a, 0x97, 0xc6, 0xec, 0x57, 0x68,
    0xb5, 0xb7, 0x0b, 0x93, 0x0c, 0x5a, 0xa7, 0xfa, 0x9a, 0xde};

// SHA-256 hash of kTestData1 ++ kTestData2 ++ kTestData3 (excluding terminating
// NUL).
const uint8_t kHashOfTestData1To3[] = {
    0xcb, 0xf6, 0x8b, 0xf1, 0x0f, 0x80, 0x03, 0xdb, 0x86, 0xb3, 0x13,
    0x43, 0xaf, 0xac, 0x8c, 0x71, 0x75, 0xbd, 0x03, 0xfb, 0x5f, 0xc9,
    0x05, 0x65, 0x0f, 0x8c, 0x80, 0xaf, 0x08, 0x74, 0x43, 0xa8};

}  // namespace

class BaseFileTest : public testing::Test {
 public:
  static const unsigned char kEmptySha256Hash[crypto::kSHA256Length];

  BaseFileTest()
      : expect_file_survives_(false),
        expect_in_progress_(true),
        expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE) {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    base_file_.reset(new BaseFile(net::NetLogWithSource()));
  }

  void TearDown() override {
    EXPECT_FALSE(base_file_->in_progress());
    if (!expected_error_) {
      EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
                base_file_->bytes_so_far());
    }

    base::FilePath full_path = base_file_->full_path();

    if (!expected_data_.empty() && !expected_error_) {
      // Make sure the data has been properly written to disk.
      std::string disk_data;
      EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data));
      EXPECT_EQ(expected_data_, disk_data);
    }

    // Make sure the mock BrowserThread outlives the BaseFile to satisfy
    // thread checks inside it.
    base_file_.reset();

    EXPECT_EQ(expect_file_survives_, base::PathExists(full_path));
  }

  bool InitializeFile() {
    DownloadInterruptReason result = base_file_->Initialize(
        base::FilePath(), temp_dir_.GetPath(), base::File(), 0, std::string(),
        std::unique_ptr<crypto::SecureHash>(), false);
    EXPECT_EQ(expected_error_, result);
    return result == DOWNLOAD_INTERRUPT_REASON_NONE;
  }

  bool AppendDataToFile(const std::string& data) {
    EXPECT_EQ(expect_in_progress_, base_file_->in_progress());
    DownloadInterruptReason result =
        base_file_->AppendDataToFile(data.data(), data.size());
    if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
      EXPECT_TRUE(expect_in_progress_) << " result = " << result;

    EXPECT_EQ(expected_error_, result);
    if (base_file_->in_progress()) {
      expected_data_ += data;
      if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
        EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
                  base_file_->bytes_so_far());
      }
    }
    return result == DOWNLOAD_INTERRUPT_REASON_NONE;
  }

  void set_expected_data(const std::string& data) { expected_data_ = data; }

  // Helper functions.
  // Create a file.  Returns the complete file path.
  base::FilePath CreateTestFile() {
    base::FilePath file_name;
    BaseFile file((net::NetLogWithSource()));

    EXPECT_EQ(
        DOWNLOAD_INTERRUPT_REASON_NONE,
        file.Initialize(base::FilePath(), temp_dir_.GetPath(), base::File(), 0,
                        std::string(), std::unique_ptr<crypto::SecureHash>(),
                        false));
    file_name = file.full_path();
    EXPECT_NE(base::FilePath::StringType(), file_name.value());

    EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
              file.AppendDataToFile(kTestData4, kTestDataLength4));

    // Keep the file from getting deleted when existing_file_name is deleted.
    file.Detach();

    return file_name;
  }

  // Create a file with the specified file name.
  void CreateFileWithName(const base::FilePath& file_name) {
    EXPECT_NE(base::FilePath::StringType(), file_name.value());
    BaseFile duplicate_file((net::NetLogWithSource()));
    EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
              duplicate_file.Initialize(file_name, temp_dir_.GetPath(),
                                        base::File(), 0, std::string(),
                                        std::unique_ptr<crypto::SecureHash>(),
                                        false));
    // Write something into it.
    duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4);
    // Detach the file so it isn't deleted on destruction of |duplicate_file|.
    duplicate_file.Detach();
  }

  int64_t CurrentSpeedAtTime(base::TimeTicks current_time) {
    EXPECT_TRUE(base_file_.get());
    return base_file_->CurrentSpeedAtTime(current_time);
  }

  base::TimeTicks StartTick() {
    EXPECT_TRUE(base_file_.get());
    return base_file_->start_tick_;
  }

  void set_expected_error(DownloadInterruptReason err) {
    expected_error_ = err;
  }

  void ExpectPermissionError(DownloadInterruptReason err) {
    EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR ||
                err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)
        << "Interrupt reason = " << err;
  }

  template <size_t SZ>
  static void ExpectHashValue(const uint8_t (&expected_hash)[SZ],
                              std::unique_ptr<crypto::SecureHash> hash_state) {
    std::vector<uint8_t> hash_value(hash_state->GetHashLength());
    hash_state->Finish(&hash_value.front(), hash_value.size());
    ASSERT_EQ(SZ, hash_value.size());
    EXPECT_EQ(0, memcmp(expected_hash, &hash_value.front(), hash_value.size()));
  }

 protected:
  // BaseClass instance we are testing.
  std::unique_ptr<BaseFile> base_file_;

  // Temporary directory for renamed downloads.
  base::ScopedTempDir temp_dir_;

  // Expect the file to survive deletion of the BaseFile instance.
  bool expect_file_survives_;

  // Expect the file to be in progress.
  bool expect_in_progress_;

 private:
  // Keep track of what data should be saved to the disk file.
  std::string expected_data_;
  DownloadInterruptReason expected_error_;

  TestBrowserThreadBundle thread_bundle_;
};

// This will initialize the entire array to zero.
const unsigned char BaseFileTest::kEmptySha256Hash[] = { 0 };

// Test the most basic scenario: just create the object and do a sanity check
// on all its accessors. This is actually a case that rarely happens
// in production, where we would at least Initialize it.
TEST_F(BaseFileTest, CreateDestroy) {
  EXPECT_EQ(base::FilePath().value(), base_file_->full_path().value());
}

// Cancel the download explicitly.
TEST_F(BaseFileTest, Cancel) {
  ASSERT_TRUE(InitializeFile());
  EXPECT_TRUE(base::PathExists(base_file_->full_path()));
  base_file_->Cancel();
  EXPECT_FALSE(base::PathExists(base_file_->full_path()));
  EXPECT_NE(base::FilePath().value(), base_file_->full_path().value());
}

// Write data to the file and detach it, so it doesn't get deleted
// automatically when base_file_ is destructed.
TEST_F(BaseFileTest, WriteAndDetach) {
  ASSERT_TRUE(InitializeFile());
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  base_file_->Finish();
  base_file_->Detach();
  expect_file_survives_ = true;
}

// Write data to the file and detach it, and calculate its sha256 hash.
TEST_F(BaseFileTest, WriteWithHashAndDetach) {
  ASSERT_TRUE(InitializeFile());
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  ExpectHashValue(kHashOfTestData1, base_file_->Finish());
  base_file_->Detach();
  expect_file_survives_ = true;
}

// Rename the file after writing to it, then detach.
TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
  ASSERT_TRUE(InitializeFile());

  base::FilePath initial_path(base_file_->full_path());
  EXPECT_TRUE(base::PathExists(initial_path));
  base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
  EXPECT_FALSE(base::PathExists(new_path));

  ASSERT_TRUE(AppendDataToFile(kTestData1));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
  EXPECT_FALSE(base::PathExists(initial_path));
  EXPECT_TRUE(base::PathExists(new_path));

  ExpectHashValue(kHashOfTestData1, base_file_->Finish());
  base_file_->Detach();
  expect_file_survives_ = true;
}

// Write data to the file once.
TEST_F(BaseFileTest, SingleWrite) {
  ASSERT_TRUE(InitializeFile());
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  ExpectHashValue(kHashOfTestData1, base_file_->Finish());
}

// Write data to the file multiple times.
TEST_F(BaseFileTest, MultipleWrites) {
  ASSERT_TRUE(InitializeFile());
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Write data to the file multiple times, interrupt it, and continue using
// another file.  Calculate the resulting combined sha256 hash.
TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
  ASSERT_TRUE(InitializeFile());
  // Write some data
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  // Get the hash state and file name.
  std::unique_ptr<crypto::SecureHash> hash_state = base_file_->Finish();

  base::FilePath new_file_path(temp_dir_.GetPath().Append(
      base::FilePath(FILE_PATH_LITERAL("second_file"))));

  ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path));

  // Create another file
  BaseFile second_file((net::NetLogWithSource()));
  ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            second_file.Initialize(new_file_path,
                                   base::FilePath(),
                                   base::File(),
                                   base_file_->bytes_so_far(),
                                   std::string(),
                                   std::move(hash_state),
                                   false));
  std::string data(kTestData3);
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            second_file.AppendDataToFile(data.data(), data.size()));
  ExpectHashValue(kHashOfTestData1To3, second_file.Finish());
}

// Rename the file after all writes to it.
TEST_F(BaseFileTest, WriteThenRename) {
  ASSERT_TRUE(InitializeFile());

  base::FilePath initial_path(base_file_->full_path());
  EXPECT_TRUE(base::PathExists(initial_path));
  base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
  EXPECT_FALSE(base::PathExists(new_path));

  ASSERT_TRUE(AppendDataToFile(kTestData1));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Rename(new_path));
  EXPECT_FALSE(base::PathExists(initial_path));
  EXPECT_TRUE(base::PathExists(new_path));

  ExpectHashValue(kHashOfTestData1, base_file_->Finish());
}

// Rename the file while the download is still in progress.
TEST_F(BaseFileTest, RenameWhileInProgress) {
  ASSERT_TRUE(InitializeFile());

  base::FilePath initial_path(base_file_->full_path());
  EXPECT_TRUE(base::PathExists(initial_path));
  base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
  EXPECT_FALSE(base::PathExists(new_path));

  ASSERT_TRUE(AppendDataToFile(kTestData1));

  EXPECT_TRUE(base_file_->in_progress());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
  EXPECT_FALSE(base::PathExists(initial_path));
  EXPECT_TRUE(base::PathExists(new_path));

  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));

  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Test that a failed rename reports the correct error.
TEST_F(BaseFileTest, RenameWithError) {
  ASSERT_TRUE(InitializeFile());

  // TestDir is a subdirectory in |temp_dir_| that we will make read-only so
  // that the rename will fail.
  base::FilePath test_dir(temp_dir_.GetPath().AppendASCII("TestDir"));
  ASSERT_TRUE(base::CreateDirectory(test_dir));

  base::FilePath new_path(test_dir.AppendASCII("TestFile"));
  EXPECT_FALSE(base::PathExists(new_path));

  {
    base::FilePermissionRestorer restore_permissions_for(test_dir);
    ASSERT_TRUE(base::MakeFileUnwritable(test_dir));
    ExpectPermissionError(base_file_->Rename(new_path));
  }

  base_file_->Finish();
}

// Test that if a rename fails for an in-progress BaseFile, it remains writeable
// and renameable.
TEST_F(BaseFileTest, RenameWithErrorInProgress) {
  ASSERT_TRUE(InitializeFile());

  base::FilePath test_dir(temp_dir_.GetPath().AppendASCII("TestDir"));
  ASSERT_TRUE(base::CreateDirectory(test_dir));

  base::FilePath new_path(test_dir.AppendASCII("TestFile"));
  EXPECT_FALSE(base::PathExists(new_path));

  // Write some data to start with.
  ASSERT_TRUE(AppendDataToFile(kTestData1));
  ASSERT_TRUE(base_file_->in_progress());

  base::FilePath old_path = base_file_->full_path();

  {
    base::FilePermissionRestorer restore_permissions_for(test_dir);
    ASSERT_TRUE(base::MakeFileUnwritable(test_dir));
    ExpectPermissionError(base_file_->Rename(new_path));

    // The file should still be open and we should be able to continue writing
    // to it.
    ASSERT_TRUE(base_file_->in_progress());
    ASSERT_TRUE(AppendDataToFile(kTestData2));
    ASSERT_EQ(old_path.value(), base_file_->full_path().value());

    // Try to rename again, just for kicks. It should still fail.
    ExpectPermissionError(base_file_->Rename(new_path));
  }

  // Now that TestDir is writeable again, we should be able to successfully
  // rename the file.
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
  ASSERT_EQ(new_path.value(), base_file_->full_path().value());
  ASSERT_TRUE(AppendDataToFile(kTestData3));

  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Test that a failed write reports an error.
TEST_F(BaseFileTest, WriteWithError) {
  base::FilePath path;
  ASSERT_TRUE(base::CreateTemporaryFile(&path));

  // Pass a file handle which was opened without the WRITE flag.
  // This should result in an error when writing.
  base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
  base_file_.reset(new BaseFile(net::NetLogWithSource()));
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(path, base::FilePath(), std::move(file), 0,
                                   std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
#if defined(OS_WIN)
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
#elif defined (OS_POSIX)
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
#endif
  ASSERT_FALSE(AppendDataToFile(kTestData1));
  base_file_->Finish();
}

// Try to write to uninitialized file.
TEST_F(BaseFileTest, UninitializedFile) {
  expect_in_progress_ = false;
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  EXPECT_FALSE(AppendDataToFile(kTestData1));
}

// Create two |BaseFile|s with the same file, and attempt to write to both.
// Overwrite base_file_ with another file with the same name and
// non-zero contents, and make sure the last file to close 'wins'.
TEST_F(BaseFileTest, DuplicateBaseFile) {
  ASSERT_TRUE(InitializeFile());

  // Create another |BaseFile| referring to the file that |base_file_| owns.
  CreateFileWithName(base_file_->full_path());

  ASSERT_TRUE(AppendDataToFile(kTestData1));
  base_file_->Finish();
}

// Create a file and append to it.
TEST_F(BaseFileTest, AppendToBaseFile) {
  // Create a new file.
  base::FilePath existing_file_name = CreateTestFile();
  set_expected_data(kTestData4);

  // Use the file we've just created.
  base_file_.reset(new BaseFile(net::NetLogWithSource()));
  ASSERT_EQ(
      DOWNLOAD_INTERRUPT_REASON_NONE,
      base_file_->Initialize(existing_file_name, base::FilePath(), base::File(),
                             kTestDataLength4, std::string(),
                             std::unique_ptr<crypto::SecureHash>(),
                             false));

  const base::FilePath file_name = base_file_->full_path();
  EXPECT_NE(base::FilePath::StringType(), file_name.value());

  // Write into the file.
  EXPECT_TRUE(AppendDataToFile(kTestData1));

  base_file_->Finish();
  base_file_->Detach();
  expect_file_survives_ = true;
}

// Create a read-only file and attempt to write to it.
TEST_F(BaseFileTest, ReadonlyBaseFile) {
  // Create a new file.
  base::FilePath readonly_file_name = CreateTestFile();

  // Restore permissions to the file when we are done with this test.
  base::FilePermissionRestorer restore_permissions(readonly_file_name);

  // Make it read-only.
  EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name));

  // Try to overwrite it.
  base_file_.reset(new BaseFile(net::NetLogWithSource()));
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
            base_file_->Initialize(readonly_file_name, base::FilePath(),
                                   base::File(), 0, std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));

  expect_in_progress_ = false;

  const base::FilePath file_name = base_file_->full_path();
  EXPECT_NE(base::FilePath::StringType(), file_name.value());

  // Write into the file.
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  EXPECT_FALSE(AppendDataToFile(kTestData1));

  base_file_->Finish();
  base_file_->Detach();
  expect_file_survives_ = true;
}

// Open an existing file and continue writing to it. The hash of the partial
// file is known and matches the existing contents.
TEST_F(BaseFileTest, ExistingBaseFileKnownHash) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  ASSERT_EQ(kTestDataLength1,
            base::WriteFile(file_path, kTestData1, kTestDataLength1));

  std::string hash_so_far(std::begin(kHashOfTestData1),
                          std::end(kHashOfTestData1));
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength1, hash_so_far,
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_data(kTestData1);
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Open an existing file and continue writing to it. The hash of the partial
// file is unknown.
TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  ASSERT_EQ(kTestDataLength1,
            base::WriteFile(file_path, kTestData1, kTestDataLength1));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength1, std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_data(kTestData1);
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Open an existing file. The contentsof the file doesn't match the known hash.
TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  ASSERT_EQ(kTestDataLength2,
            base::WriteFile(file_path, kTestData2, kTestDataLength2));

  std::string hash_so_far(std::begin(kHashOfTestData1),
                          std::end(kHashOfTestData1));
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength2, hash_so_far,
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
}

// Open a large existing file with a known hash and continue writing to it.
TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  std::string big_buffer(1024 * 200, 'a');
  ASSERT_EQ(static_cast<int>(big_buffer.size()),
            base::WriteFile(file_path, big_buffer.data(), big_buffer.size()));

  // Hash of partial file (1024*200 * 'a')
  const uint8_t kExpectedPartialHash[] = {
      0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab,
      0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b,
      0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c};

  // Hash of entire file (1024*400 * 'a')
  const uint8_t kExpectedFullHash[] = {
      0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83,
      0xc5, 0x09, 0x16, 0xbc, 0x5e, 0x2d, 0x07, 0x95, 0xb9, 0x42, 0x20,
      0x41, 0x7c, 0xb3, 0x38, 0xd3, 0xf4, 0xe0, 0x78, 0x89, 0x46};

  ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   big_buffer.size(),
                                   std::string(std::begin(kExpectedPartialHash),
                                               std::end(kExpectedPartialHash)),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_data(big_buffer);  // Contents of the file on Open.
  ASSERT_TRUE(AppendDataToFile(big_buffer));
  ExpectHashValue(kExpectedFullHash, base_file_->Finish());
}

// Open a large existing file. The contents doesn't match the known hash.
TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  std::string big_buffer(1024 * 200, 'a');
  ASSERT_EQ(static_cast<int>(big_buffer.size()),
            base::WriteFile(file_path, big_buffer.data(), big_buffer.size()));

  // Incorrect hash of partial file (1024*200 * 'a')
  const uint8_t kExpectedPartialHash[] = {
      0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b,
      0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24,
      0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5};

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   big_buffer.size(),
                                   std::string(std::begin(kExpectedPartialHash),
                                               std::end(kExpectedPartialHash)),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
}

// Open an existing file. The size of the file is too short.
TEST_F(BaseFileTest, ExistingBaseFileTooShort) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  ASSERT_EQ(kTestDataLength1,
            base::WriteFile(file_path, kTestData1, kTestDataLength1));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength1 + 1, std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT);
}

// Open an existing file. The size is larger than expected.
TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  std::string contents;
  contents.append(kTestData1);
  contents.append("Something extra");
  ASSERT_EQ(static_cast<int>(contents.size()),
            base::WriteFile(file_path, contents.data(), contents.size()));

  std::string hash_so_far(std::begin(kHashOfTestData1),
                          std::end(kHashOfTestData1));
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength1, hash_so_far,
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_data(kTestData1);  // Our starting position.
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Open an existing file. The size is large than expected and the hash is
// unknown.
TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  std::string contents;
  contents.append(kTestData1);
  contents.append("Something extra");
  ASSERT_EQ(static_cast<int>(contents.size()),
            base::WriteFile(file_path, contents.data(), contents.size()));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kTestDataLength1, std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  set_expected_data(kTestData1);
  ASSERT_TRUE(AppendDataToFile(kTestData2));
  ASSERT_TRUE(AppendDataToFile(kTestData3));
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

// Similar to ExistingBaseFileKnownHashTooLong test, but with a file large
// enough to requre multiple Read()s to complete. This provides additional code
// coverage for the CalculatePartialHash() logic.
TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLongForLargeFile) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  const size_t kFileSize = 1024 * 1024;
  const size_t kIntermediateSize = kFileSize / 2 + 111;
  // |contents| is 100 bytes longer than kIntermediateSize. The latter is the
  // expected size.
  std::string contents(kIntermediateSize + 100, 'a');
  ASSERT_EQ(static_cast<int>(contents.size()),
            base::WriteFile(file_path, contents.data(), contents.size()));

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
            base_file_->Initialize(file_path, base::FilePath(), base::File(),
                                   kIntermediateSize, std::string(),
                                   std::unique_ptr<crypto::SecureHash>(),
                                   false));
  // The extra bytes should be stripped during Initialize().
  contents.resize(kIntermediateSize, 'a');
  set_expected_data(contents);
  std::string new_data(kFileSize - kIntermediateSize, 'a');
  ASSERT_TRUE(AppendDataToFile(new_data));
  const uint8_t kExpectedHash[] = {
      0x9b, 0xc1, 0xb2, 0xa2, 0x88, 0xb2, 0x6a, 0xf7, 0x25, 0x7a, 0x36,
      0x27, 0x7a, 0xe3, 0x81, 0x6a, 0x7d, 0x4f, 0x16, 0xe8, 0x9c, 0x1e,
      0x7e, 0x77, 0xd0, 0xa5, 0xc4, 0x8b, 0xad, 0x62, 0xb3, 0x60,
  };
  ExpectHashValue(kExpectedHash, base_file_->Finish());
}

// Test that a temporary file is created in the default download directory.
TEST_F(BaseFileTest, CreatedInDefaultDirectory) {
  ASSERT_TRUE(base_file_->full_path().empty());
  ASSERT_TRUE(InitializeFile());
  EXPECT_FALSE(base_file_->full_path().empty());

  // On Windows, CreateTemporaryFileInDir() will cause a path with short names
  // to be expanded into a path with long names. Thus temp_dir.GetPath() might
  // not
  // be a string-wise match to base_file_->full_path().DirName() even though
  // they are in the same directory.
  base::FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file));
  ASSERT_FALSE(temp_file.empty());
  EXPECT_STREQ(temp_file.DirName().value().c_str(),
               base_file_->full_path().DirName().value().c_str());
  base_file_->Finish();
}

TEST_F(BaseFileTest, NoDoubleDeleteAfterCancel) {
  ASSERT_TRUE(InitializeFile());
  base::FilePath full_path = base_file_->full_path();
  ASSERT_FALSE(full_path.empty());
  ASSERT_TRUE(base::PathExists(full_path));

  base_file_->Cancel();
  ASSERT_FALSE(base::PathExists(full_path));

  const char kData[] = "hello";
  const int kDataLength = static_cast<int>(arraysize(kData) - 1);
  ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength));
  // The file that we created here should stick around when the BaseFile is
  // destroyed during TearDown.
  expect_file_survives_ = true;
}

// Test that writing data to a sparse file works.
TEST_F(BaseFileTest, WriteDataToSparseFile) {
  base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
  std::string contents = kTestData1;
  ASSERT_EQ(static_cast<int>(contents.size()),
            base::WriteFile(file_path, contents.data(), contents.size()));

  base_file_->Initialize(file_path, base::FilePath(), base::File(),
                         kTestDataLength1,
                         std::string(),
                         std::unique_ptr<crypto::SecureHash>(),
                         true);
  // This will create a hole in the file.
  base_file_->WriteDataToFile(kTestDataLength1 + kTestDataLength2,
                              kTestData3,
                              kTestDataLength3);
  // This should fill the hole.
  base_file_->WriteDataToFile(kTestDataLength1,
                              kTestData2,
                              kTestDataLength2);
  set_expected_data(contents + kTestData2 + kTestData3);
  ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}

}  // namespace content
