// Copyright 2013 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 "storage/browser/fileapi/recursive_operation_delegate.h"

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/test/sandbox_file_system_test_helper.h"
#include "storage/browser/fileapi/file_system_file_util.h"
#include "storage/browser/fileapi/file_system_operation.h"
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "testing/gtest/include/gtest/gtest.h"

using storage::FileSystemContext;
using storage::FileSystemOperationContext;
using storage::FileSystemURL;

namespace content {
namespace {

class LoggingRecursiveOperation : public storage::RecursiveOperationDelegate {
 public:
  struct LogEntry {
    enum Type {
      PROCESS_FILE,
      PROCESS_DIRECTORY,
      POST_PROCESS_DIRECTORY
    };
    Type type;
    FileSystemURL url;
  };

  LoggingRecursiveOperation(FileSystemContext* file_system_context,
                            const FileSystemURL& root,
                            const StatusCallback& callback)
      : storage::RecursiveOperationDelegate(file_system_context),
        root_(root),
        callback_(callback),
        weak_factory_(this) {}
  ~LoggingRecursiveOperation() override {}

  const std::vector<LogEntry>& log_entries() const { return log_entries_; }

  // RecursiveOperationDelegate overrides.
  void Run() override { NOTREACHED(); }

  void RunRecursively() override {
    StartRecursiveOperation(
        root_, storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT, callback_);
  }

  void RunRecursivelyWithIgnoringError() {
    StartRecursiveOperation(
        root_, storage::FileSystemOperation::ERROR_BEHAVIOR_SKIP, callback_);
  }

  void ProcessFile(const FileSystemURL& url,
                   const StatusCallback& callback) override {
    RecordLogEntry(LogEntry::PROCESS_FILE, url);

    if (error_url_.is_valid() && error_url_ == url) {
      callback.Run(base::File::FILE_ERROR_FAILED);
      return;
    }

    operation_runner()->GetMetadata(
        url, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY,
        base::Bind(&LoggingRecursiveOperation::DidGetMetadata,
                   weak_factory_.GetWeakPtr(), callback));
  }

  void ProcessDirectory(const FileSystemURL& url,
                        const StatusCallback& callback) override {
    RecordLogEntry(LogEntry::PROCESS_DIRECTORY, url);
    callback.Run(base::File::FILE_OK);
  }

  void PostProcessDirectory(const FileSystemURL& url,
                            const StatusCallback& callback) override {
    RecordLogEntry(LogEntry::POST_PROCESS_DIRECTORY, url);
    callback.Run(base::File::FILE_OK);
  }

  void SetEntryToFail(const FileSystemURL& url) { error_url_ = url; }

 private:
  void RecordLogEntry(LogEntry::Type type, const FileSystemURL& url) {
    LogEntry entry;
    entry.type = type;
    entry.url = url;
    log_entries_.push_back(entry);
  }

  void DidGetMetadata(const StatusCallback& callback,
                      base::File::Error result,
                      const base::File::Info& file_info) {
    if (result != base::File::FILE_OK) {
      callback.Run(result);
      return;
    }

    callback.Run(file_info.is_directory ?
                 base::File::FILE_ERROR_NOT_A_FILE :
                 base::File::FILE_OK);
  }

  FileSystemURL root_;
  StatusCallback callback_;
  std::vector<LogEntry> log_entries_;
  FileSystemURL error_url_;

  base::WeakPtrFactory<LoggingRecursiveOperation> weak_factory_;
  DISALLOW_COPY_AND_ASSIGN(LoggingRecursiveOperation);
};

void ReportStatus(base::File::Error* out_error,
                  base::File::Error error) {
  DCHECK(out_error);
  *out_error = error;
}

// To test the Cancel() during operation, calls Cancel() of |operation|
// after |counter| times message posting.
void CallCancelLater(storage::RecursiveOperationDelegate* operation,
                     int counter) {
  if (counter > 0) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&CallCancelLater, base::Unretained(operation), counter - 1));
    return;
  }

  operation->Cancel();
}

}  // namespace

class RecursiveOperationDelegateTest : public testing::Test {
 protected:
  void SetUp() override {
    EXPECT_TRUE(base_.CreateUniqueTempDir());
    sandbox_file_system_.SetUp(base_.GetPath().AppendASCII("filesystem"));
  }

  void TearDown() override { sandbox_file_system_.TearDown(); }

  std::unique_ptr<FileSystemOperationContext> NewContext() {
    FileSystemOperationContext* context =
        sandbox_file_system_.NewOperationContext();
    // Grant enough quota for all test cases.
    context->set_allowed_bytes_growth(1000000);
    return base::WrapUnique(context);
  }

  storage::FileSystemFileUtil* file_util() {
    return sandbox_file_system_.file_util();
  }

  FileSystemURL URLForPath(const std::string& path) const {
    return sandbox_file_system_.CreateURLFromUTF8(path);
  }

  FileSystemURL CreateFile(const std::string& path) {
    FileSystemURL url = URLForPath(path);
    bool created = false;
    EXPECT_EQ(base::File::FILE_OK,
              file_util()->EnsureFileExists(NewContext().get(),
                                            url, &created));
    EXPECT_TRUE(created);
    return url;
  }

  FileSystemURL CreateDirectory(const std::string& path) {
    FileSystemURL url = URLForPath(path);
    EXPECT_EQ(base::File::FILE_OK,
              file_util()->CreateDirectory(NewContext().get(), url,
                                           false /* exclusive */, true));
    return url;
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  // Common temp base for nondestructive uses.
  base::ScopedTempDir base_;
  SandboxFileSystemTestHelper sandbox_file_system_;
};

TEST_F(RecursiveOperationDelegateTest, RootIsFile) {
  FileSystemURL src_file(CreateFile("src"));

  base::File::Error error = base::File::FILE_ERROR_FAILED;
  std::unique_ptr<FileSystemOperationContext> context = NewContext();
  std::unique_ptr<LoggingRecursiveOperation> operation(
      new LoggingRecursiveOperation(context->file_system_context(), src_file,
                                    base::Bind(&ReportStatus, &error)));
  operation->RunRecursively();
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(base::File::FILE_OK, error);

  const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
      operation->log_entries();
  ASSERT_EQ(1U, log_entries.size());
  const LoggingRecursiveOperation::LogEntry& entry = log_entries[0];
  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, entry.type);
  EXPECT_EQ(src_file, entry.url);
}

TEST_F(RecursiveOperationDelegateTest, RootIsDirectory) {
  FileSystemURL src_root(CreateDirectory("src"));
  FileSystemURL src_dir1(CreateDirectory("src/dir1"));
  FileSystemURL src_file1(CreateFile("src/file1"));
  FileSystemURL src_file2(CreateFile("src/dir1/file2"));
  FileSystemURL src_file3(CreateFile("src/dir1/file3"));

  base::File::Error error = base::File::FILE_ERROR_FAILED;
  std::unique_ptr<FileSystemOperationContext> context = NewContext();
  std::unique_ptr<LoggingRecursiveOperation> operation(
      new LoggingRecursiveOperation(context->file_system_context(), src_root,
                                    base::Bind(&ReportStatus, &error)));
  operation->RunRecursively();
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(base::File::FILE_OK, error);

  const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
      operation->log_entries();
  ASSERT_EQ(8U, log_entries.size());

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[0].type);
  EXPECT_EQ(src_root, log_entries[0].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
            log_entries[1].type);
  EXPECT_EQ(src_root, log_entries[1].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[2].type);
  EXPECT_EQ(src_file1, log_entries[2].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
            log_entries[3].type);
  EXPECT_EQ(src_dir1, log_entries[3].url);

  // The order of src/dir1/file2 and src/dir1/file3 depends on the file system
  // implementation (can be swapped).
  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[4].type);
  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[5].type);
  EXPECT_TRUE((src_file2 == log_entries[4].url &&
               src_file3 == log_entries[5].url) ||
              (src_file3 == log_entries[4].url &&
               src_file2 == log_entries[5].url));

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
            log_entries[6].type);
  EXPECT_EQ(src_dir1, log_entries[6].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
            log_entries[7].type);
  EXPECT_EQ(src_root, log_entries[7].url);
}

TEST_F(RecursiveOperationDelegateTest, Cancel) {
  FileSystemURL src_root(CreateDirectory("src"));
  FileSystemURL src_dir1(CreateDirectory("src/dir1"));
  FileSystemURL src_file1(CreateFile("src/file1"));
  FileSystemURL src_file2(CreateFile("src/dir1/file2"));

  base::File::Error error = base::File::FILE_ERROR_FAILED;
  std::unique_ptr<FileSystemOperationContext> context = NewContext();
  std::unique_ptr<LoggingRecursiveOperation> operation(
      new LoggingRecursiveOperation(context->file_system_context(), src_root,
                                    base::Bind(&ReportStatus, &error)));
  operation->RunRecursively();

  // Invoke Cancel(), after 5 times message posting.
  CallCancelLater(operation.get(), 5);
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(base::File::FILE_ERROR_ABORT, error);
}

TEST_F(RecursiveOperationDelegateTest, AbortWithError) {
  FileSystemURL src_root(CreateDirectory("src"));
  FileSystemURL src_dir1(CreateDirectory("src/dir1"));
  FileSystemURL src_file1(CreateFile("src/file1"));
  FileSystemURL src_file2(CreateFile("src/dir1/file2"));
  FileSystemURL src_file3(CreateFile("src/dir1/file3"));

  base::File::Error error = base::File::FILE_ERROR_FAILED;
  std::unique_ptr<FileSystemOperationContext> context = NewContext();
  std::unique_ptr<LoggingRecursiveOperation> operation(
      new LoggingRecursiveOperation(context->file_system_context(), src_root,
                                    base::Bind(&ReportStatus, &error)));
  operation->SetEntryToFail(src_file1);
  operation->RunRecursively();
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(base::File::FILE_ERROR_FAILED, error);

  // Confirm that operation has been aborted in the middle.
  const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
      operation->log_entries();
  ASSERT_EQ(3U, log_entries.size());

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[0].type);
  EXPECT_EQ(src_root, log_entries[0].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
            log_entries[1].type);
  EXPECT_EQ(src_root, log_entries[1].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[2].type);
  EXPECT_EQ(src_file1, log_entries[2].url);
}

TEST_F(RecursiveOperationDelegateTest, ContinueWithError) {
  FileSystemURL src_root(CreateDirectory("src"));
  FileSystemURL src_dir1(CreateDirectory("src/dir1"));
  FileSystemURL src_file1(CreateFile("src/file1"));
  FileSystemURL src_file2(CreateFile("src/dir1/file2"));
  FileSystemURL src_file3(CreateFile("src/dir1/file3"));

  base::File::Error error = base::File::FILE_ERROR_FAILED;
  std::unique_ptr<FileSystemOperationContext> context = NewContext();
  std::unique_ptr<LoggingRecursiveOperation> operation(
      new LoggingRecursiveOperation(context->file_system_context(), src_root,
                                    base::Bind(&ReportStatus, &error)));
  operation->SetEntryToFail(src_file1);
  operation->RunRecursivelyWithIgnoringError();
  base::RunLoop().RunUntilIdle();

  // Error code should be base::File::FILE_ERROR_FAILED.
  ASSERT_EQ(base::File::FILE_ERROR_FAILED, error);

  // Confirm that operation continues after the error.
  const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
      operation->log_entries();
  ASSERT_EQ(8U, log_entries.size());

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[0].type);
  EXPECT_EQ(src_root, log_entries[0].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
            log_entries[1].type);
  EXPECT_EQ(src_root, log_entries[1].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[2].type);
  EXPECT_EQ(src_file1, log_entries[2].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
            log_entries[3].type);
  EXPECT_EQ(src_dir1, log_entries[3].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[4].type);
  EXPECT_EQ(src_file3, log_entries[4].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
            log_entries[5].type);
  EXPECT_EQ(src_file2, log_entries[5].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
            log_entries[6].type);
  EXPECT_EQ(src_dir1, log_entries[6].url);

  EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
            log_entries[7].type);
  EXPECT_EQ(src_root, log_entries[7].url);
}

}  // namespace content
