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

#include <base/bind.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/test/simple_test_tick_clock.h>
#include <dbus/mock_bus.h>
#include <dbus/object_path.h>
#include <dbus/smbprovider/dbus-constants.h>
#include <gtest/gtest.h>

#include "smbprovider/fake_kerberos_artifact_client.h"
#include "smbprovider/fake_samba_interface.h"
#include "smbprovider/fake_samba_proxy.h"
#include "smbprovider/iterator/directory_iterator.h"
#include "smbprovider/kerberos_artifact_synchronizer.h"
#include "smbprovider/metadata_cache.h"
#include "smbprovider/mount_config.h"
#include "smbprovider/mount_manager.h"
#include "smbprovider/netbios_packet_parser.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/smbprovider.h"
#include "smbprovider/smbprovider_helper.h"
#include "smbprovider/smbprovider_test_helper.h"
#include "smbprovider/temp_file_manager.h"

namespace smbprovider {
namespace {

using brillo::dbus_utils::DBusObject;

// arbitary D-Bus
constexpr int32_t kDBusSerial = 123;

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

DirectoryEntryListProto GetDirectoryEntryListProtoFromBlob(
    const ProtoBlob& blob) {
  DirectoryEntryListProto entries;
  EXPECT_TRUE(entries.ParseFromArray(blob.data(), blob.size()));

  return entries;
}

HostnamesProto GetHostnamesProtoFromBlob(const ProtoBlob& blob) {
  HostnamesProto hostnames_proto;
  EXPECT_TRUE(hostnames_proto.ParseFromArray(blob.data(), blob.size()));

  return hostnames_proto;
}

void ExpectKerberosCallback(bool expected_result,
                            std::unique_ptr<dbus::Response> response) {
  EXPECT_TRUE(response.get());
  dbus::MessageReader reader(response.get());
  bool result;
  EXPECT_TRUE(reader.PopBool(&result));
  EXPECT_EQ(expected_result, result);
}

}  // namespace

class SmbProviderTest : public testing::Test {
 public:
  std::unique_ptr<SambaInterface> SambaInterfaceFactoryFunction(
      FakeSambaInterface* fake_samba,
      MountManager* mount_manager,
      const MountConfig& mount_config) {
    enable_ntlm_ = mount_config.enable_ntlm;
    return std::make_unique<FakeSambaProxy>(fake_samba);
  }

  SmbProviderTest() { SetUpSmbProvider(false /* enable_metadata_cache */); }
  SmbProviderTest(const SmbProviderTest&) = delete;
  SmbProviderTest& operator=(const SmbProviderTest&) = delete;

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

  // Sets up SmbProvider with caching set to |enable_metadata_cache|. This is
  // called by default before each test with caching disabled. Pass true and
  // call as the first line in a test to enable caching.
  void SetUpSmbProvider(bool enable_metadata_cache) {
    fake_samba_ = std::make_unique<FakeSambaInterface>();

    auto tick_clock = std::make_unique<base::SimpleTestTickClock>();
    fake_tick_clock_ = tick_clock.get();

    auto mount_tracker = std::make_unique<MountTracker>(std::move(tick_clock),
                                                        enable_metadata_cache);

    auto samba_interface_factory =
        base::BindRepeating(&SmbProviderTest::SambaInterfaceFactoryFunction,
                            base::Unretained(this), fake_samba_.get());

    auto mount_manager_ptr = std::make_unique<MountManager>(
        std::move(mount_tracker), samba_interface_factory);

    mount_manager_ = mount_manager_ptr.get();

    auto fake_artifact_client = std::make_unique<FakeKerberosArtifactClient>();
    kerberos_client_ = fake_artifact_client.get();

    // Make sure there is a fresh directory in the case this is called more
    // than once.
    if (krb_temp_dir_.IsValid()) {
      EXPECT_TRUE(krb_temp_dir_.Delete());
    }
    EXPECT_TRUE(krb_temp_dir_.CreateUniqueTempDir());

    if (daemon_store_temp_dir_.IsValid()) {
      EXPECT_TRUE(daemon_store_temp_dir_.Delete());
    }
    EXPECT_TRUE(daemon_store_temp_dir_.CreateUniqueTempDir());

    krb5_conf_path_ = CreateKrb5ConfPath(krb_temp_dir_.GetPath());
    krb5_ccache_path_ = CreateKrb5CCachePath(krb_temp_dir_.GetPath());

    auto kerberos_artifact_synchronizer =
        std::make_unique<KerberosArtifactSynchronizer>(
            krb5_conf_path_, krb5_ccache_path_, std::move(fake_artifact_client),
            false /* allow_credentials_update */);
    kerberos_synchronizer_ = kerberos_artifact_synchronizer.get();

    const dbus::ObjectPath object_path("/object/path");
    smbprovider_ = std::make_unique<SmbProvider>(
        std::make_unique<DBusObject>(nullptr, mock_bus_, object_path),
        std::move(mount_manager_ptr), std::move(kerberos_artifact_synchronizer),
        daemon_store_temp_dir_.GetPath());

    metadata_cache_ = std::make_unique<MetadataCache>(
        fake_tick_clock_,
        base::TimeDelta::FromMicroseconds(kMetadataCacheLifetimeMicroseconds),
        MetadataCache::Mode::kDisabled);
  }

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

  bool GetRootPath(int32_t mount_id, std::string* mount_path) const {
    return mount_manager_->GetFullPath(mount_id, "" /* entry_path */,
                                       mount_path);
  }

  void CreateDaemonStoreForUser(const std::string& user_hash) {
    base::File::Error error = base::File::FILE_OK;
    EXPECT_TRUE(base::CreateDirectoryAndGetError(
        daemon_store_temp_dir_.GetPath().Append(base::FilePath(user_hash)),
        &error))
        << "CreateDaemonStoreForUser error: " << error;
  }

  std::string krb5_conf_path_;
  std::string krb5_ccache_path_;
  base::ScopedTempDir krb_temp_dir_;
  base::ScopedTempDir daemon_store_temp_dir_;
  scoped_refptr<dbus::MockBus> mock_bus_ =
      new dbus::MockBus(dbus::Bus::Options());
  std::unique_ptr<SmbProvider> smbprovider_;
  std::unique_ptr<FakeSambaInterface> fake_samba_;
  base::SimpleTestTickClock* fake_tick_clock_;
  MountManager* mount_manager_;
  TempFileManager temp_file_manager_;
  FakeKerberosArtifactClient* kerberos_client_;
  KerberosArtifactSynchronizer* kerberos_synchronizer_;
  // |metadata_cache| is used to test the GetEntries method
  std::unique_ptr<MetadataCache> metadata_cache_;
  bool enable_ntlm_ = false;
};

TEST_F(SmbProviderTest, GetSharesFailsOnEmptyProto) {
  ProtoBlob empty_blob;
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(empty_blob, &error, &result);
  EXPECT_EQ(ERROR_DBUS_PARSE_FAILED, CastError(error));
}

TEST_F(SmbProviderTest, GetSharesFailsOnNonExistentServer) {
  ProtoBlob blob = CreateGetSharesOptionsBlob("smb://0.0.0.1");
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_NOT_FOUND, CastError(error));
}

TEST_F(SmbProviderTest, GetSharesSucceedsOnEmptyServer) {
  const std::string server_url = "smb://192.168.0.1";
  fake_samba_->AddServer(server_url);

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));
  EXPECT_TRUE(GetDirectoryEntryListProtoFromBlob(result).entries().empty());
}

TEST_F(SmbProviderTest, GetSharesSucceedsWithSingleShare) {
  const std::string server_url = "smb://192.168.0.1";
  const std::string share = "share1";

  fake_samba_->AddServer(server_url);
  fake_samba_->AddShare(server_url + "/" + share);

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));

  DirectoryEntryListProto dir_entry_list =
      GetDirectoryEntryListProtoFromBlob(result);
  EXPECT_EQ(dir_entry_list.entries().size(), 1);

  const DirectoryEntryProto& entry = dir_entry_list.entries(0);
  EXPECT_EQ(entry.name(), share);
  EXPECT_TRUE(entry.is_directory());
}

TEST_F(SmbProviderTest, GetSharesSucceedsWithMultipleShares) {
  const std::string server_url = "smb://192.168.0.1";
  const std::string share1 = "share1";
  const std::string share2 = "share2";

  fake_samba_->AddServer(server_url);
  fake_samba_->AddShare(server_url + "/" + share1);
  fake_samba_->AddShare(server_url + "/" + share2);

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));

  DirectoryEntryListProto dir_entry_list =
      GetDirectoryEntryListProtoFromBlob(result);
  EXPECT_EQ(dir_entry_list.entries().size(), 2);

  const DirectoryEntryProto& entry1 = dir_entry_list.entries(0);
  EXPECT_EQ(entry1.name(), share1);
  EXPECT_TRUE(entry1.is_directory());

  const DirectoryEntryProto& entry2 = dir_entry_list.entries(1);
  EXPECT_EQ(entry2.name(), share2);
  EXPECT_TRUE(entry2.is_directory());
}

TEST_F(SmbProviderTest, GetSharesDoesntReturnSelfAndParentEntries) {
  const std::string server_url = "smb://192.168.0.1";
  const std::string share1 = "share1";

  fake_samba_->AddServer(server_url);
  fake_samba_->AddShare(server_url + "/" + share1);

  // These shouldn't be returned by GetShares.
  fake_samba_->AddShare(server_url + "/.");
  fake_samba_->AddShare(server_url + "/..");

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));

  DirectoryEntryListProto dir_entry_list =
      GetDirectoryEntryListProtoFromBlob(result);
  EXPECT_EQ(dir_entry_list.entries().size(), 1);

  const DirectoryEntryProto& entry1 = dir_entry_list.entries(0);
  EXPECT_EQ(entry1.name(), share1);
  EXPECT_TRUE(entry1.is_directory());
}

TEST_F(SmbProviderTest, GetSharesDoesntReturnNonShareEntries) {
  const std::string server_url = "smb://192.168.0.1";
  const std::string share1 = "share1";

  fake_samba_->AddServer(server_url);
  fake_samba_->AddShare(server_url + "/" + share1);

  // These shouldn't be returned by GetShares since they aren't shares.
  fake_samba_->AddDirectory(server_url + "/dir");
  fake_samba_->AddFile(server_url + "/file");

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));

  DirectoryEntryListProto dir_entry_list =
      GetDirectoryEntryListProtoFromBlob(result);
  EXPECT_EQ(dir_entry_list.entries().size(), 1);

  const DirectoryEntryProto& entry1 = dir_entry_list.entries(0);
  EXPECT_EQ(entry1.name(), share1);
  EXPECT_TRUE(entry1.is_directory());
}

TEST_F(SmbProviderTest, GetSharesReturnsShareContainingDirectory) {
  const std::string server_url = "smb://192.168.0.1";
  const std::string share1 = "share1";

  fake_samba_->AddServer(server_url);
  fake_samba_->AddShare(server_url + "/" + share1);

  // Add a directory in the share.
  fake_samba_->AddDirectory(server_url + "/" + share1 + "/dir");

  ProtoBlob blob = CreateGetSharesOptionsBlob(server_url);
  int32_t error;
  ProtoBlob result;

  smbprovider_->GetShares(blob, &error, &result);
  EXPECT_EQ(ERROR_OK, CastError(error));

  DirectoryEntryListProto dir_entry_list =
      GetDirectoryEntryListProtoFromBlob(result);
  EXPECT_EQ(dir_entry_list.entries().size(), 1);

  const DirectoryEntryProto& entry1 = dir_entry_list.entries(0);
  EXPECT_EQ(entry1.name(), share1);
  EXPECT_TRUE(entry1.is_directory());
}

TEST_F(SmbProviderTest, SetupKerberosWritesKerberosFilesSuccessfully) {
  const std::string user = "test user";
  const std::string krb5cc = "test creds";
  const std::string krb5conf = "test conf";

  authpolicy::KerberosFiles kerberos_files =
      CreateKerberosFilesProto(krb5cc, krb5conf);
  kerberos_client_->AddKerberosFiles(user, kerberos_files);

  dbus::MethodCall method_call(kSmbProviderInterface, "SetupKerberos");
  method_call.SetSerial(kDBusSerial);

  SmbProvider::SetupKerberosCallback callback =
      std::make_unique<brillo::dbus_utils::DBusMethodResponse<bool>>(
          &method_call,
          base::BindOnce(&ExpectKerberosCallback, true /* expected_result*/));

  smbprovider_->SetupKerberos(std::move(callback), user);

  ExpectFileEqual(krb5_conf_path_, krb5conf);
  ExpectFileEqual(krb5_ccache_path_, krb5cc);
}

TEST_F(SmbProviderTest, SetupKerberosFailsWhenKerberosFilesDoNotExist) {
  const std::string user = "test user";

  dbus::MethodCall method_call(kSmbProviderInterface, "SetupKerberos");
  method_call.SetSerial(kDBusSerial);

  SmbProvider::SetupKerberosCallback callback =
      std::make_unique<brillo::dbus_utils::DBusMethodResponse<bool>>(
          &method_call,
          base::BindOnce(&ExpectKerberosCallback, false /* expected_result*/));

  smbprovider_->SetupKerberos(std::move(callback), user);
}

TEST_F(SmbProviderTest, ParseNetBiosPacketSucceedsOnValidPacket) {
  const std::string name_string("testname");
  const std::vector<uint8_t> name(name_string.begin(), name_string.end());
  const uint8_t name_length(name.size());
  const uint16_t transaction_id(123);
  const std::string hostname_1 = "hostname1";
  const std::string hostname_2 = "hostname2";
  const std::vector<std::vector<uint8_t>> hostnames = {
      CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType),
      CreateValidNetBiosHostname(hostname_2, netbios::kFileServerNodeType)};

  const std::vector<uint8_t> valid_packet = CreateNetBiosResponsePacket(
      hostnames, name_length, name, transaction_id, 0x20 /* response_type */);

  ProtoBlob blob =
      smbprovider_->ParseNetBiosPacket(valid_packet, transaction_id);

  const HostnamesProto hostnames_proto = GetHostnamesProtoFromBlob(blob);
  EXPECT_EQ(2, hostnames_proto.hostnames().size());
  EXPECT_EQ(hostname_1, hostnames_proto.hostnames(0));
  EXPECT_EQ(hostname_2, hostnames_proto.hostnames(1));
}

TEST_F(SmbProviderTest, ParseNetBiosPacketFailsOnInvalidPacket) {
  const std::vector<uint8_t> invalid_packet;

  ProtoBlob blob =
      smbprovider_->ParseNetBiosPacket(invalid_packet, 0 /* transaction_id */);

  const HostnamesProto hostnames_proto = GetHostnamesProtoFromBlob(blob);
  EXPECT_EQ(0, hostnames_proto.hostnames().size());
}

}  // namespace smbprovider
