// 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/bind_helpers.h>
#include <base/message_loop/message_loop.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::MessageLoopForIO message_loop_;
};

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
