// Copyright 2017 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 "smbprovider/smbprovider.h"
#include "smbprovider/constants.h"
#include "smbprovider/fake_samba_interface.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/smbprovider_helper.h"

#include <base/memory/ptr_util.h>
#include <dbus/mock_bus.h>
#include <dbus/object_path.h>
#include <gtest/gtest.h>
#include <utility>

using brillo::dbus_utils::DBusObject;
using dbus::MockBus;
using dbus::ObjectPath;

namespace smbprovider {

namespace {

constexpr size_t kFileSize = 10;
constexpr char kValidPath[] = "/path/valid";
constexpr char kValidSharePath[] = "smb://wdshare/test";

ErrorType CastError(int error) {
  EXPECT_GE(error, 0);
  return static_cast<ErrorType>(error);
}

}  // namespace

class SmbProviderTest : public testing::Test {
 public:
  SmbProviderTest() { SetSmbProviderBuffer(kBufferSize); }

 protected:
  using DirEntries = std::vector<smbc_dirent>;

  ProtoBlob WriteMountOptions(const std::string& path) {
    ProtoBlob proto_blob;
    MountOptions mount_options;
    mount_options.set_path(path);
    EXPECT_EQ(ERROR_OK, SerializeProtoToBlob(mount_options, &proto_blob));
    return proto_blob;
  }

  void WriteUnmountOptions(int32_t mount_id, ProtoBlob* proto_blob) {
    UnmountOptions unmount_options;
    unmount_options.set_mount_id(mount_id);
    ASSERT_EQ(ERROR_OK, SerializeProtoToBlob(unmount_options, proto_blob));
  }

  // Helper method that adds |kValidSharePath| as a mountable share and mounts
  // it.
  int32_t PrepareMount() {
    fake_samba_->AddDirectory(std::string(kValidSharePath));
    int32_t mount_id;
    int32_t err;
    ProtoBlob proto_blob = WriteMountOptions(kValidSharePath);
    smbprovider_->Mount(proto_blob, &err, &mount_id);
    EXPECT_EQ(ERROR_OK, CastError(err));
    ExpectNoOpenDirectories();
    return mount_id;
  }

  void SetSmbProviderBuffer(int32_t buffer_size) {
    std::unique_ptr<FakeSambaInterface> fake_ptr =
        base::MakeUnique<FakeSambaInterface>();
    fake_samba_ = fake_ptr.get();
    const ObjectPath object_path(std::string("/object/path"));
    smbprovider_.reset(new SmbProvider(
        base::MakeUnique<DBusObject>(nullptr, mock_bus_, object_path),
        std::move(fake_ptr), buffer_size));
  }

  // Helper method that asserts there are no entries that have not been
  // closed.
  void ExpectNoOpenDirectories() {
    EXPECT_FALSE(fake_samba_->HasOpenDirectories());
  }

  scoped_refptr<MockBus> mock_bus_ = new MockBus(dbus::Bus::Options());
  std::unique_ptr<SmbProvider> smbprovider_;
  FakeSambaInterface* fake_samba_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SmbProviderTest);
};

// Should properly serialize protobuf.
TEST_F(SmbProviderTest, ShouldSerializeProto) {
  const std::string path("smb://192.168.0.1/test");
  MountOptions mount_options;
  mount_options.set_path(path);
  ProtoBlob buffer;
  EXPECT_EQ(ERROR_OK, SerializeProtoToBlob(mount_options, &buffer));
  EXPECT_EQ(mount_options.ByteSizeLong(), buffer.size());

  MountOptions deserialized_proto;
  EXPECT_TRUE(deserialized_proto.ParseFromArray(buffer.data(), buffer.size()));
  EXPECT_EQ(path, deserialized_proto.path());
}

// Mount fails when mounting a share that doesn't exist.
TEST_F(SmbProviderTest, MountFailsWithInvalidShare) {
  int32_t mount_id;
  int32_t err;
  ProtoBlob proto_blob = WriteMountOptions("/test/invalid");
  smbprovider_->Mount(proto_blob, &err, &mount_id);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(err));
  ExpectNoOpenDirectories();
}

// Unmount fails when unmounting an |mount_id| that wasn't previously mounted.
TEST_F(SmbProviderTest, UnmountFailsWithUnmountedShare) {
  ProtoBlob proto_blob;
  WriteUnmountOptions(123, &proto_blob);
  int32_t error = smbprovider_->Unmount(proto_blob);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(error));
  ExpectNoOpenDirectories();
}

// Mounting different shares should return different mount ids.
TEST_F(SmbProviderTest, MountReturnsDifferentMountIds) {
  const std::string share1("smb://wdshare/dogs");
  const std::string share2("smb://wdshare/cats");
  fake_samba_->AddDirectory(share1);
  fake_samba_->AddDirectory(share2);
  int32_t mount1_id = -1;
  int32_t mount2_id = -1;
  int32_t error;
  ProtoBlob proto_blob_1 = WriteMountOptions(share1);
  ProtoBlob proto_blob_2 = WriteMountOptions(share2);
  smbprovider_->Mount(proto_blob_1, &error, &mount1_id);
  smbprovider_->Mount(proto_blob_2, &error, &mount2_id);
  EXPECT_NE(mount1_id, mount2_id);
}

// Mount and unmount succeed when mounting a valid share path and unmounting
// using the |mount_id| from |Mount|.
TEST_F(SmbProviderTest, MountUnmountSucceedsWithValidShare) {
  int32_t mount_id = PrepareMount();
  ExpectNoOpenDirectories();

  ProtoBlob proto_blob;
  WriteUnmountOptions(mount_id, &proto_blob);
  int32_t error = smbprovider_->Unmount(proto_blob);
  EXPECT_EQ(ERROR_OK, CastError(error));
  ExpectNoOpenDirectories();
}

// Mount ids should not be reused.
TEST_F(SmbProviderTest, MountIdsDontGetReused) {
  const std::string share("smb://wdshare/dogs");
  fake_samba_->AddDirectory(share);
  int32_t mount_id1 = -1;
  int32_t error;
  ProtoBlob mount_options_blob1 = WriteMountOptions(share);
  smbprovider_->Mount(mount_options_blob1, &error, &mount_id1);

  ProtoBlob unmount_options_blob;
  WriteUnmountOptions(mount_id1, &unmount_options_blob);
  EXPECT_EQ(ERROR_OK, CastError(smbprovider_->Unmount(unmount_options_blob)));

  int32_t mount_id2 = -1;
  ProtoBlob mount_options_blob2 = WriteMountOptions(share);
  smbprovider_->Mount(mount_options_blob2, &error, &mount_id2);
  EXPECT_NE(mount_id1, mount_id2);
}

// ReadDirectory fails when passed a |mount_id| that wasn't previously mounted.
TEST_F(SmbProviderTest, ReadDirectoryFailsWithUnmountedShare) {
  ProtoBlob results;
  int32_t err;
  smbprovider_->ReadDirectory(999, std::string(kValidPath), &err, &results);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(err));
  ExpectNoOpenDirectories();
}

// Read directory fails when passed a path that doesn't exist.
TEST_F(SmbProviderTest, ReadDirectoryFailsWithInvalidDir) {
  int32_t mount_id = PrepareMount();

  ProtoBlob results;
  int32_t err;
  smbprovider_->ReadDirectory(mount_id, std::string("/test/invalid"), &err,
                              &results);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(err));
}

// ReadDirectory succeeds when reading an empty directory.
TEST_F(SmbProviderTest, ReadDirectorySucceedsWithEmptyDir) {
  int32_t mount_id = PrepareMount();

  fake_samba_->AddDirectory(
      AppendPath(std::string(kValidSharePath), std::string(kValidPath)));

  ProtoBlob results;
  int32_t err;
  smbprovider_->ReadDirectory(mount_id, std::string(kValidPath), &err,
                              &results);

  DirectoryEntryList entries;
  const std::string parsed_proto(results.begin(), results.end());
  EXPECT_TRUE(entries.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(err));
  EXPECT_EQ(0, entries.entries_size());
  ExpectNoOpenDirectories();
}

// Read directory succeeds but does not return files when it exceeds the buffer
// size.
TEST_F(SmbProviderTest, ReadDirectoryDoesNotReturnEntryWithSmallBuffer) {
  // Construct smbprovider_ with buffer size of 1.
  SetSmbProviderBuffer(1);
  int32_t mount_id = PrepareMount();

  int32_t dir_id = fake_samba_->AddDirectory(
      AppendPath(std::string(kValidSharePath), std::string(kValidPath)));
  const std::string file("file.jpg");
  fake_samba_->AddEntry(dir_id, file, SMBC_FILE, kFileSize);

  ProtoBlob results;
  int32_t error_code;
  smbprovider_->ReadDirectory(mount_id, std::string(kValidPath), &error_code,
                              &results);

  DirectoryEntryList entries;
  const std::string parsed_proto(results.begin(), results.end());
  EXPECT_TRUE(entries.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(error_code));
  EXPECT_EQ(0, entries.entries_size());
}

// Read directory succeeds when the buffer size is just big enough for one
// entry. This should return one entry, and ReadDirectory will loop through the
// buffer again from the beginning.
TEST_F(SmbProviderTest, ReadDirectorySucceedsWithMultipleUsageOfSmallBuffer) {
  const std::string file_name1("file1.jpg");
  const std::string file_name2("file2.jpg");
  size_t buffer_size = CalculateEntrySize(file_name1) + 1;

  SetSmbProviderBuffer(buffer_size);
  int32_t mount_id = PrepareMount();

  int32_t dir_id = fake_samba_->AddDirectory(
      AppendPath(std::string(kValidSharePath), std::string(kValidPath)));
  fake_samba_->AddEntry(dir_id, file_name1, SMBC_FILE, kFileSize);
  fake_samba_->AddEntry(dir_id, file_name2, SMBC_FILE, kFileSize);

  ProtoBlob results;
  int32_t error_code;
  smbprovider_->ReadDirectory(mount_id, std::string(kValidPath), &error_code,
                              &results);

  DirectoryEntryList entries;
  const std::string parsed_proto(results.begin(), results.end());
  EXPECT_TRUE(entries.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(error_code));
  EXPECT_EQ(2, entries.entries_size());

  const DirectoryEntry& entry1 = entries.entries(0);
  EXPECT_FALSE(entry1.is_directory());
  EXPECT_EQ(file_name1, entry1.name());

  const DirectoryEntry& entry2 = entries.entries(1);
  EXPECT_FALSE(entry2.is_directory());
  EXPECT_EQ(file_name2, entry2.name());
}

// Read directory succeeds and returns expected entries.
TEST_F(SmbProviderTest, ReadDirectorySucceedsWithNonEmptyDir) {
  int32_t mount_id = PrepareMount();

  int32_t dir_id = fake_samba_->AddDirectory(
      AppendPath(std::string(kValidSharePath), std::string(kValidPath)));
  const std::string file("file.jpg");
  const std::string dir("images");
  fake_samba_->AddEntry(dir_id, file, SMBC_FILE, kFileSize);
  fake_samba_->AddEntry(dir_id, dir, SMBC_DIR, 0);

  ProtoBlob results;
  int32_t error_code;
  smbprovider_->ReadDirectory(mount_id, std::string(kValidPath), &error_code,
                              &results);

  DirectoryEntryList entries;
  const std::string parsed_proto(results.begin(), results.end());
  EXPECT_TRUE(entries.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(error_code));
  EXPECT_EQ(2, entries.entries_size());

  const DirectoryEntry& entry1 = entries.entries(0);
  EXPECT_FALSE(entry1.is_directory());
  EXPECT_EQ(file, entry1.name());

  const DirectoryEntry& entry2 = entries.entries(1);
  EXPECT_TRUE(entry2.is_directory());
  EXPECT_EQ(dir, entry2.name());
}

// Read directory succeeds and omits "." and ".." entries.
TEST_F(SmbProviderTest, ReadDirectoryDoesntReturnSelfAndParententries) {
  int32_t mount_id = PrepareMount();

  int32_t dir_id = fake_samba_->AddDirectory(
      AppendPath(std::string(kValidSharePath), std::string(kValidPath)));
  const std::string file("file.jpg");
  fake_samba_->AddEntry(dir_id, file, SMBC_FILE, kFileSize);
  fake_samba_->AddEntry(dir_id, std::string(kEntrySelf), SMBC_DIR, 0);
  fake_samba_->AddEntry(dir_id, std::string(kEntryParent), SMBC_DIR, 0);

  ProtoBlob results;
  int32_t error_code;
  smbprovider_->ReadDirectory(mount_id, std::string(kValidPath), &error_code,
                              &results);

  DirectoryEntryList entries;
  const std::string parsed_proto(results.begin(), results.end());
  EXPECT_TRUE(entries.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(error_code));
  EXPECT_EQ(1, entries.entries_size());

  const DirectoryEntry& entry = entries.entries(0);
  EXPECT_FALSE(entry.is_directory());
  EXPECT_EQ(file, entry.name());
}

// GetMetadata fails with when passed a |mount_id| that wasn't previously
// mounted.
TEST_F(SmbProviderTest, GetMetadataFailsWithUnmountedShare) {
  int32_t err;
  ProtoBlob result;
  smbprovider_->GetMetadataEntry(123, std::string(kValidPath), &err, &result);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(err));
}

// GetMetadata fails when passed a path that doesn't exist.
TEST_F(SmbProviderTest, GetMetadataFailsWithInvalidPath) {
  int32_t mount_id = PrepareMount();

  ProtoBlob result;
  int32_t error_code;
  smbprovider_->GetMetadataEntry(mount_id, std::string("/test/invalid"),
                                 &error_code, &result);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(error_code));
}

// GetMetadata succeeds when passed a valid share path.
TEST_F(SmbProviderTest, GetMetadataSucceeds) {
  int32_t mount_id = PrepareMount();
  const std::string dir_path =
      AppendPath(std::string(kValidSharePath), std::string(kValidPath));
  const std::string name("dog.jpg");
  // Add an entry path since chrome passes us entry paths with a leading '/'.
  const std::string entry_path = "/" + name;

  int32_t dir_id = fake_samba_->AddDirectory(dir_path);
  fake_samba_->AddEntry(dir_id, name, SMBC_FILE, kFileSize);

  ProtoBlob result;
  int32_t error_code;
  smbprovider_->GetMetadataEntry(
      mount_id, AppendPath(std::string(kValidPath), entry_path), &error_code,
      &result);

  DirectoryEntry entry;
  const std::string parsed_proto(result.begin(), result.end());
  EXPECT_TRUE(entry.ParseFromString(parsed_proto));

  EXPECT_EQ(ERROR_OK, CastError(error_code));
  EXPECT_FALSE(entry.is_directory());
  EXPECT_EQ(name, entry.name());
  EXPECT_EQ(kFileSize, entry.size());
}

}  // namespace smbprovider
