// 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 <list>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/i18n/file_util_icu.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "net/base/directory_lister.h"
#include "net/base/net_errors.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

using net::test::IsError;
using net::test::IsOk;

namespace net {

namespace {

const int kMaxDepth = 3;
const int kBranchingFactor = 4;
const int kFilesPerDirectory = 5;

class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
 public:
  explicit ListerDelegate(DirectoryLister::ListingType type)
      : cancel_lister_on_list_file_(false),
        cancel_lister_on_list_done_(false),
        lister_(nullptr),
        done_(false),
        error_(-1),
        type_(type) {}

  // When set to true, this signals that the directory list operation should be
  // cancelled (And the run loop quit) in the first call to OnListFile.
  void set_cancel_lister_on_list_file(bool cancel_lister_on_list_file) {
    cancel_lister_on_list_file_ = cancel_lister_on_list_file;
  }

  // When set to true, this signals that the directory list operation should be
  // cancelled (And the run loop quit) when OnDone is called.
  void set_cancel_lister_on_list_done(bool cancel_lister_on_list_done) {
    cancel_lister_on_list_done_ = cancel_lister_on_list_done;
  }

  void OnListFile(const DirectoryLister::DirectoryListerData& data) override {
    ASSERT_FALSE(done_);

    file_list_.push_back(data.info);
    paths_.push_back(data.path);
    if (cancel_lister_on_list_file_) {
      lister_->Cancel();
      run_loop.Quit();
    }
  }

  void OnListDone(int error) override {
    ASSERT_FALSE(done_);

    done_ = true;
    error_ = error;
    if (type_ == DirectoryLister::ALPHA_DIRS_FIRST)
      CheckSort();

    if (cancel_lister_on_list_done_)
      lister_->Cancel();
    run_loop.Quit();
  }

  void CheckSort() {
    // Check that we got files in the right order.
    if (!file_list_.empty()) {
      for (size_t previous = 0, current = 1;
           current < file_list_.size();
           previous++, current++) {
        // Directories should come before files.
        if (file_list_[previous].IsDirectory() &&
            !file_list_[current].IsDirectory()) {
          continue;
        }
        EXPECT_NE(FILE_PATH_LITERAL(".."),
                  file_list_[current].GetName().BaseName().value());
        EXPECT_EQ(file_list_[previous].IsDirectory(),
                  file_list_[current].IsDirectory());
        EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames(
            file_list_[previous].GetName(),
            file_list_[current].GetName()));
      }
    }
  }

  void Run(DirectoryLister* lister) {
    lister_ = lister;
    lister_->Start();
    run_loop.Run();
  }

  int error() const { return error_; }

  int num_files() const { return file_list_.size(); }

  bool done() const { return done_; }

 private:
  bool cancel_lister_on_list_file_;
  bool cancel_lister_on_list_done_;

  // This is owned by the individual tests, rather than the ListerDelegate.
  DirectoryLister* lister_;

  base::RunLoop run_loop;

  bool done_;
  int error_;
  DirectoryLister::ListingType type_;

  std::vector<base::FileEnumerator::FileInfo> file_list_;
  std::vector<base::FilePath> paths_;
};

}  // namespace

class DirectoryListerTest : public PlatformTest,
                            public WithScopedTaskEnvironment {
 public:
  DirectoryListerTest()
      : total_created_file_system_objects_in_temp_root_dir_(0),
        created_file_system_objects_in_temp_root_dir_(0) {}

  void SetUp() override {
    // Randomly create a directory structure of depth 3 in a temporary root
    // directory.
    std::list<std::pair<base::FilePath, int> > directories;
    ASSERT_TRUE(temp_root_dir_.CreateUniqueTempDir());
    directories.push_back(std::make_pair(temp_root_dir_.GetPath(), 0));
    while (!directories.empty()) {
      std::pair<base::FilePath, int> dir_data = directories.front();
      directories.pop_front();
      for (int i = 0; i < kFilesPerDirectory; i++) {
        std::string file_name = base::StringPrintf("file_id_%d", i);
        base::FilePath file_path = dir_data.first.AppendASCII(file_name);
        base::File file(file_path,
                        base::File::FLAG_CREATE | base::File::FLAG_WRITE);
        ASSERT_TRUE(file.IsValid());
        ++total_created_file_system_objects_in_temp_root_dir_;
        if (dir_data.first == temp_root_dir_.GetPath())
          ++created_file_system_objects_in_temp_root_dir_;
      }
      if (dir_data.second < kMaxDepth - 1) {
        for (int i = 0; i < kBranchingFactor; i++) {
          std::string dir_name = base::StringPrintf("child_dir_%d", i);
          base::FilePath dir_path = dir_data.first.AppendASCII(dir_name);
          ASSERT_TRUE(base::CreateDirectory(dir_path));
          ++total_created_file_system_objects_in_temp_root_dir_;
          if (dir_data.first == temp_root_dir_.GetPath())
            ++created_file_system_objects_in_temp_root_dir_;
          directories.push_back(std::make_pair(dir_path, dir_data.second + 1));
        }
      }
    }
    PlatformTest::SetUp();
  }

  const base::FilePath& root_path() const { return temp_root_dir_.GetPath(); }

  int expected_list_length_recursive() const {
    // List should include everything but the top level directory, and does not
    // include "..".
    return total_created_file_system_objects_in_temp_root_dir_;
  }

  int expected_list_length_non_recursive() const {
    // List should include everything in the top level directory, and "..".
    return created_file_system_objects_in_temp_root_dir_ + 1;
  }

 private:
  // Number of files and directories created in SetUp, excluding
  // |temp_root_dir_| itself.  Includes all nested directories and their files.
  int total_created_file_system_objects_in_temp_root_dir_;
  // Number of files and directories created directly in |temp_root_dir_|.
  int created_file_system_objects_in_temp_root_dir_;

  base::ScopedTempDir temp_root_dir_;
};

TEST_F(DirectoryListerTest, BigDirTest) {
  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(root_path(), &delegate);
  delegate.Run(&lister);

  EXPECT_TRUE(delegate.done());
  EXPECT_THAT(delegate.error(), IsOk());
  EXPECT_EQ(expected_list_length_non_recursive(), delegate.num_files());
}

TEST_F(DirectoryListerTest, BigDirRecursiveTest) {
  ListerDelegate delegate(DirectoryLister::NO_SORT_RECURSIVE);
  DirectoryLister lister(root_path(), DirectoryLister::NO_SORT_RECURSIVE,
                         &delegate);
  delegate.Run(&lister);

  EXPECT_TRUE(delegate.done());
  EXPECT_THAT(delegate.error(), IsOk());
  EXPECT_EQ(expected_list_length_recursive(), delegate.num_files());
}

TEST_F(DirectoryListerTest, EmptyDirTest) {
  base::ScopedTempDir tempDir;
  EXPECT_TRUE(tempDir.CreateUniqueTempDir());

  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(tempDir.GetPath(), &delegate);
  delegate.Run(&lister);

  EXPECT_TRUE(delegate.done());
  EXPECT_THAT(delegate.error(), IsOk());
  // Contains only the parent directory ("..").
  EXPECT_EQ(1, delegate.num_files());
}

// This doesn't really test much, except make sure calling cancel before any
// callbacks are invoked doesn't crash.  Can't wait for all tasks running on a
// worker pool to complete, unfortunately.
// TODO(mmenke):  See if there's a way to make this fail more reliably on
// regression.
TEST_F(DirectoryListerTest, BasicCancelTest) {
  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  std::unique_ptr<DirectoryLister> lister(
      new DirectoryLister(root_path(), &delegate));
  lister->Start();
  lister->Cancel();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(delegate.done());
  EXPECT_EQ(0, delegate.num_files());
}

TEST_F(DirectoryListerTest, CancelOnListFileTest) {
  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(root_path(), &delegate);
  delegate.set_cancel_lister_on_list_file(true);
  delegate.Run(&lister);

  EXPECT_FALSE(delegate.done());
  EXPECT_EQ(1, delegate.num_files());
}

TEST_F(DirectoryListerTest, CancelOnListDoneTest) {
  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(root_path(), &delegate);
  delegate.set_cancel_lister_on_list_done(true);
  delegate.Run(&lister);

  EXPECT_TRUE(delegate.done());
  EXPECT_THAT(delegate.error(), IsOk());
  EXPECT_EQ(expected_list_length_non_recursive(), delegate.num_files());
}

TEST_F(DirectoryListerTest, CancelOnLastElementTest) {
  base::ScopedTempDir tempDir;
  EXPECT_TRUE(tempDir.CreateUniqueTempDir());

  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(tempDir.GetPath(), &delegate);
  delegate.set_cancel_lister_on_list_file(true);
  delegate.Run(&lister);

  EXPECT_FALSE(delegate.done());
  // Contains only the parent directory ("..").
  EXPECT_EQ(1, delegate.num_files());
}

TEST_F(DirectoryListerTest, NoSuchDirTest) {
  base::ScopedTempDir tempDir;
  EXPECT_TRUE(tempDir.CreateUniqueTempDir());

  ListerDelegate delegate(DirectoryLister::ALPHA_DIRS_FIRST);
  DirectoryLister lister(
      tempDir.GetPath().AppendASCII("this_path_does_not_exist"), &delegate);
  delegate.Run(&lister);

  EXPECT_THAT(delegate.error(), IsError(ERR_FILE_NOT_FOUND));
  EXPECT_EQ(0, delegate.num_files());
}

}  // namespace net
