// Copyright 2020 The Chromium OS 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 "smbfs/recursive_delete_operation.h"

#include <sys/stat.h>
#include <sys/types.h>

#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/callback_helpers.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "smbfs/samba_interface_impl.h"
#include "smbfs/smb_credential.h"
#include "smbfs/smb_filesystem.h"

namespace smbfs {
namespace {

using ::testing::_;
using ::testing::Return;

constexpr char kSharePath[] = "smb://server/share";
constexpr char kDirectoryToDelete[] = "/the/directory";
constexpr char kFileToDelete[] = "/the/directory/file";

class MockSmbFilesystemDelegate : public SmbFilesystem::Delegate {
 public:
  MOCK_METHOD(void,
              RequestCredentials,
              (RequestCredentialsCallback),
              (override));
};

class MockSambaInterface : public SambaInterfaceImpl {
 public:
  MOCK_METHOD(int, UnlinkFile, (const std::string&), (override));
  MOCK_METHOD(int, RemoveDirectory, (const std::string&), (override));
  MOCK_METHOD(int, CloseDirectory, (SMBCFILE*), (override));
  MOCK_METHOD(int, OpenDirectory, (const std::string&, SMBCFILE**), (override));
  MOCK_METHOD(int,
              ReadDirectory,
              (SMBCFILE*, const struct libsmb_file_info**, struct stat*),
              (override));
};

class MockSmbFilesystem : public SmbFilesystem {
 public:
  MockSmbFilesystem()
      : SmbFilesystem(&mock_delegate_, kSharePath),
        mock_samba_impl_(new MockSambaInterface()) {
    const std::vector<uint8_t> empty_ip_address;
    SetResolvedAddress(empty_ip_address);
    SetSambaInterface(std::unique_ptr<SambaInterface>(mock_samba_impl_));
  }

  MockSambaInterface* samba_impl() { return mock_samba_impl_; }

 private:
  MockSmbFilesystemDelegate mock_delegate_;
  MockSambaInterface* mock_samba_impl_;
};

class TestRecursiveDeleteOperation : public RecursiveDeleteOperation {
 public:
  explicit TestRecursiveDeleteOperation(CompletionCallback callback)
      : RecursiveDeleteOperation(nullptr,
                                 kSharePath,
                                 base::FilePath(kDirectoryToDelete),
                                 std::move(callback)) {
    SetSambaInterface(fs_.samba_impl());
  }

  MockSmbFilesystem& fs() { return fs_; }

 private:
  MockSmbFilesystem fs_;
};

}  // namespace

class RecursiveDeleteOperationTest : public testing::Test {
 protected:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
      base::test::TaskEnvironment::MainThreadType::IO};
};

TEST_F(RecursiveDeleteOperationTest, DeleteFile) {
  TestRecursiveDeleteOperation delete_operation((base::DoNothing()));

  base::FilePath file_path(kFileToDelete);
  std::string share_path = std::string(kSharePath) + file_path.value();

  EXPECT_CALL(*(delete_operation.fs().samba_impl()), UnlinkFile(_))
      .WillOnce([&](const std::string& share_file_path) -> int {
        EXPECT_EQ(share_path, share_file_path);
        return 0;
      });
  delete_operation.DeleteFile(file_path);
}

TEST_F(RecursiveDeleteOperationTest, DeleteDirectory) {
  TestRecursiveDeleteOperation delete_operation(
      base::BindOnce([](mojom::DeleteRecursivelyError error) {}));

  base::FilePath dir_path(kDirectoryToDelete);
  std::string share_path = std::string(kSharePath) + dir_path.value();

  EXPECT_CALL(*(delete_operation.fs().samba_impl()), RemoveDirectory(_))
      .WillOnce([&](const std::string& share_dir_path) -> int {
        EXPECT_EQ(share_path, share_dir_path);
        return 0;
      });
  delete_operation.DeleteDirectory(dir_path);
}

TEST_F(RecursiveDeleteOperationTest, CloseDirectory) {
  TestRecursiveDeleteOperation delete_operation(
      base::BindOnce([](mojom::DeleteRecursivelyError error) {}));

  EXPECT_CALL(*(delete_operation.fs().samba_impl()), CloseDirectory(_))
      .WillOnce([&](SMBCFILE* dir) -> int { return 0; });
  delete_operation.CloseDirectory(nullptr);
}

TEST_F(RecursiveDeleteOperationTest, GetDirectoryListing) {
  TestRecursiveDeleteOperation delete_operation(
      base::BindOnce([](mojom::DeleteRecursivelyError error) {}));

  EXPECT_CALL(*(delete_operation.fs().samba_impl()), OpenDirectory(_, _))
      .Times(1)
      .WillOnce(Return(0));
  EXPECT_CALL(*(delete_operation.fs().samba_impl()), CloseDirectory(_))
      .Times(1)
      .WillOnce(Return(0));

  // Mock out the listing of a directory with two entries: a file and a
  // subdirectory.
  struct MockEntry {
    std::string entry_name;
    struct libsmb_file_info entry_info;
    struct stat entry_stat;
  };

  int entry_count = 0;
  std::vector<MockEntry> mock_entries = {{"file_name", {0}, {0}},
                                         {"dir_name", {0}, {0}}};
  mock_entries[1].entry_stat.st_mode |= S_IFDIR;

  EXPECT_CALL(*(delete_operation.fs().samba_impl()), ReadDirectory(_, _, _))
      .Times(mock_entries.size() + 1)
      .WillRepeatedly([&](SMBCFILE* dir,
                          const struct libsmb_file_info** file_info,
                          struct stat* file_stat) -> int {
        if (entry_count < mock_entries.size()) {
          *file_info = &(mock_entries[entry_count].entry_info);
          struct libsmb_file_info** inner_file_info =
              const_cast<struct libsmb_file_info**>(file_info);
          (*inner_file_info)->name =
              const_cast<char*>(mock_entries[entry_count].entry_name.c_str());
          *file_stat = mock_entries[entry_count].entry_stat;
        } else {
          *file_info = nullptr;
        }

        entry_count++;
        return 0;
      });

  base::FilePath dir_path(kDirectoryToDelete);
  std::list<struct RecursiveDeleteOperation::Entry> entries;
  bool success = delete_operation.GetDirectoryListing(dir_path, &entries);
  EXPECT_TRUE(success);

  EXPECT_EQ(mock_entries.size(), entries.size());

  RecursiveDeleteOperation::Entry entry = entries.front();
  EXPECT_EQ(entry.path, dir_path.Append(mock_entries[0].entry_name));
  EXPECT_FALSE(entry.is_directory);

  entries.pop_front();
  entry = entries.front();
  EXPECT_EQ(entry.path.value(),
            dir_path.Append(mock_entries[1].entry_name).value());
  EXPECT_TRUE(entry.is_directory);
}

}  // namespace smbfs
