// Copyright 2018 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_test_helper.h"

#include <algorithm>
#include <utility>

#include <gtest/gtest.h>

#include "smbprovider/mount_config.h"
#include "smbprovider/netbios_packet_parser.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/temp_file_manager.h"

#include <base/check.h>
#include <base/check_op.h>

namespace smbprovider {
namespace {

ProtoBlob SerializeProtoToBlobAndCheck(
    const google::protobuf::MessageLite& proto) {
  ProtoBlob proto_blob;
  EXPECT_EQ(ERROR_OK, SerializeProtoToBlob(proto, &proto_blob));
  return proto_blob;
}

}  // namespace

MountOptionsProto CreateMountOptionsProto(const std::string& path,
                                          const std::string& original_path,
                                          const std::string& workgroup,
                                          const std::string& username,
                                          const std::string& account_hash,
                                          bool skip_connect,
                                          bool save_password,
                                          bool restore_password,
                                          const MountConfig& mount_config) {
  MountOptionsProto mount_options;
  mount_options.set_path(path);
  mount_options.set_original_path(original_path);
  mount_options.set_workgroup(workgroup);
  mount_options.set_username(username);
  mount_options.set_account_hash(account_hash);
  mount_options.set_skip_connect(skip_connect);
  mount_options.set_save_password(save_password);
  mount_options.set_restore_password(restore_password);

  std::unique_ptr<MountConfigProto> config =
      std::make_unique<MountConfigProto>();
  config->set_enable_ntlm(mount_config.enable_ntlm);

  mount_options.set_allocated_mount_config(config.release());

  return mount_options;
}

UnmountOptionsProto CreateUnmountOptionsProto(int32_t mount_id,
                                              bool remove_password) {
  UnmountOptionsProto unmount_options;
  unmount_options.set_mount_id(mount_id);
  unmount_options.set_remove_password(remove_password);
  return unmount_options;
}

ReadDirectoryOptionsProto CreateReadDirectoryOptionsProto(
    int32_t mount_id, const std::string& directory_path) {
  ReadDirectoryOptionsProto read_directory_options;
  read_directory_options.set_mount_id(mount_id);
  read_directory_options.set_directory_path(directory_path);
  return read_directory_options;
}

GetMetadataEntryOptionsProto CreateGetMetadataOptionsProto(
    int32_t mount_id, const std::string& entry_path) {
  GetMetadataEntryOptionsProto get_metadata_options;
  get_metadata_options.set_mount_id(mount_id);
  get_metadata_options.set_entry_path(entry_path);
  return get_metadata_options;
}

OpenFileOptionsProto CreateOpenFileOptionsProto(int32_t mount_id,
                                                const std::string& file_path,
                                                bool writeable) {
  OpenFileOptionsProto open_file_options;
  open_file_options.set_mount_id(mount_id);
  open_file_options.set_file_path(file_path);
  open_file_options.set_writeable(writeable);
  return open_file_options;
}

CloseFileOptionsProto CreateCloseFileOptionsProto(int32_t mount_id,
                                                  int32_t file_id) {
  CloseFileOptionsProto close_file_options;
  close_file_options.set_mount_id(mount_id);
  close_file_options.set_file_id(file_id);
  return close_file_options;
}

DeleteEntryOptionsProto CreateDeleteEntryOptionsProto(
    int32_t mount_id, const std::string& entry_path, bool recursive) {
  DeleteEntryOptionsProto delete_entry_options;
  delete_entry_options.set_mount_id(mount_id);
  delete_entry_options.set_entry_path(entry_path);
  delete_entry_options.set_recursive(recursive);
  return delete_entry_options;
}

ReadFileOptionsProto CreateReadFileOptionsProto(int32_t mount_id,
                                                int32_t file_id,
                                                int64_t offset,
                                                int32_t length) {
  ReadFileOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_file_id(file_id);
  options.set_offset(offset);
  options.set_length(length);
  return options;
}

CreateFileOptionsProto CreateCreateFileOptionsProto(
    int32_t mount_id, const std::string& file_path) {
  CreateFileOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_file_path(file_path);
  return options;
}

TruncateOptionsProto CreateTruncateOptionsProto(int32_t mount_id,
                                                const std::string& file_path,
                                                int64_t length) {
  TruncateOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_file_path(file_path);
  options.set_length(length);
  return options;
}

WriteFileOptionsProto CreateWriteFileOptionsProto(int32_t mount_id,
                                                  int32_t file_id,
                                                  int64_t offset,
                                                  int32_t length) {
  WriteFileOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_file_id(file_id);
  options.set_offset(offset);
  options.set_length(length);
  return options;
}

CreateDirectoryOptionsProto CreateCreateDirectoryOptionsProto(
    int32_t mount_id, const std::string& directory_path, bool recursive) {
  CreateDirectoryOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_directory_path(directory_path);
  options.set_recursive(recursive);
  return options;
}

MoveEntryOptionsProto CreateMoveEntryOptionsProto(
    int32_t mount_id,
    const std::string& source_path,
    const std::string& target_path) {
  MoveEntryOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_source_path(source_path);
  options.set_target_path(target_path);
  return options;
}

CopyEntryOptionsProto CreateCopyEntryOptionsProto(
    int32_t mount_id,
    const std::string& source_path,
    const std::string& target_path) {
  CopyEntryOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_source_path(source_path);
  options.set_target_path(target_path);
  return options;
}

GetDeleteListOptionsProto CreateGetDeleteListOptionsProto(
    int32_t mount_id, const std::string& entry_path) {
  GetDeleteListOptionsProto options;
  options.set_mount_id(mount_id);
  options.set_entry_path(entry_path);
  return options;
}

GetSharesOptionsProto CreateGetSharesOptionsProto(
    const std::string& server_url) {
  GetSharesOptionsProto options;
  options.set_server_url(server_url);
  return options;
}

authpolicy::KerberosFiles CreateKerberosFilesProto(
    const std::string& krb5cc, const std::string& krb5conf) {
  authpolicy::KerberosFiles kerberos_files;
  kerberos_files.set_krb5cc(krb5cc);
  kerberos_files.set_krb5conf(krb5conf);
  return kerberos_files;
}

UpdateMountCredentialsOptionsProto CreateUpdateMountCredentialsOptionsProto(
    int32_t mount_id,
    const std::string& workgroup,
    const std::string& username) {
  UpdateMountCredentialsOptionsProto update_options;
  update_options.set_mount_id(mount_id);
  update_options.set_workgroup(workgroup);
  update_options.set_username(username);

  return update_options;
}

UpdateSharePathOptionsProto CreateUpdateSharePathOptionsProto(
    int32_t mount_id, const std::string& share_path) {
  UpdateSharePathOptionsProto update_share_path_options;
  update_share_path_options.set_mount_id(mount_id);
  update_share_path_options.set_path(share_path);

  return update_share_path_options;
}

ProtoBlob CreateMountOptionsBlob(const std::string& path) {
  return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
      path, "" /* original_path */, "" /* workgroup */, "" /* username */,
      "" /* account_hash */, false /* skip_connect */,
      false /* save_password */, false /* restore_password */,
      MountConfig(true /* enable_ntlm */)));
}

ProtoBlob CreateMountOptionsBlob(const std::string& path,
                                 const MountConfig& mount_config) {
  return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
      path, "" /* original_path */, "" /* workgroup */, "" /* username */,
      "" /* account_hash */, false /* skip_connect */,
      false /* save_password */, false /* restore_password */, mount_config));
}

ProtoBlob CreateMountOptionsBlob(const std::string& path,
                                 const std::string& workgroup,
                                 const std::string& username,
                                 const MountConfig& mount_config) {
  return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
      path, "" /* original_path */, workgroup, username, "" /* account_hash */,
      false /* skip_connect */, false /* save_password */,
      false /* restore_password */, mount_config));
}

ProtoBlob CreateMountOptionsBlob(const std::string& path,
                                 const std::string& original_path,
                                 const std::string& workgroup,
                                 const std::string& username,
                                 const std::string& account_hash,
                                 bool skip_connect,
                                 bool save_password,
                                 bool restore_password,
                                 const MountConfig& mount_config) {
  return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
      path, original_path, workgroup, username, account_hash, skip_connect,
      save_password, restore_password, mount_config));
}

ProtoBlob CreateUnmountOptionsBlob(int32_t mount_id, bool remove_password) {
  return SerializeProtoToBlobAndCheck(
      CreateUnmountOptionsProto(mount_id, remove_password));
}

ProtoBlob CreateReadDirectoryOptionsBlob(int32_t mount_id,
                                         const std::string& directory_path) {
  return SerializeProtoToBlobAndCheck(
      CreateReadDirectoryOptionsProto(mount_id, directory_path));
}

ProtoBlob CreateGetMetadataOptionsBlob(int32_t mount_id,
                                       const std::string& entry_path) {
  ProtoBlob proto_blob;
  return SerializeProtoToBlobAndCheck(
      CreateGetMetadataOptionsProto(mount_id, entry_path));
}

ProtoBlob CreateOpenFileOptionsBlob(int32_t mount_id,
                                    const std::string& file_path,
                                    bool writeable) {
  return SerializeProtoToBlobAndCheck(
      CreateOpenFileOptionsProto(mount_id, file_path, writeable));
}

ProtoBlob CreateCloseFileOptionsBlob(int32_t mount_id, int32_t file_id) {
  return SerializeProtoToBlobAndCheck(
      CreateCloseFileOptionsProto(mount_id, file_id));
}

ProtoBlob CreateDeleteEntryOptionsBlob(int32_t mount_id,
                                       const std::string& entry_path,
                                       bool recursive) {
  return SerializeProtoToBlobAndCheck(
      CreateDeleteEntryOptionsProto(mount_id, entry_path, recursive));
}

ProtoBlob CreateReadFileOptionsBlob(int32_t mount_id,
                                    int32_t file_id,
                                    int64_t offset,
                                    int32_t length) {
  return SerializeProtoToBlobAndCheck(
      CreateReadFileOptionsProto(mount_id, file_id, offset, length));
}

ProtoBlob CreateCreateFileOptionsBlob(int32_t mount_id,
                                      const std::string& file_path) {
  return SerializeProtoToBlobAndCheck(
      CreateCreateFileOptionsProto(mount_id, file_path));
}

ProtoBlob CreateTruncateOptionsBlob(int32_t mount_id,
                                    const std::string& file_path,
                                    int64_t length) {
  return SerializeProtoToBlobAndCheck(
      CreateTruncateOptionsProto(mount_id, file_path, length));
}

ProtoBlob CreateWriteFileOptionsBlob(int32_t mount_id,
                                     int32_t file_id,
                                     int64_t offset,
                                     int32_t length) {
  return SerializeProtoToBlobAndCheck(
      CreateWriteFileOptionsProto(mount_id, file_id, offset, length));
}

ProtoBlob CreateCreateDirectoryOptionsBlob(int32_t mount_id,
                                           const std::string& directory_path,
                                           bool recursive) {
  return SerializeProtoToBlobAndCheck(
      CreateCreateDirectoryOptionsProto(mount_id, directory_path, recursive));
}

ProtoBlob CreateMoveEntryOptionsBlob(int32_t mount_id,
                                     const std::string& source_path,
                                     const std::string& target_path) {
  return SerializeProtoToBlobAndCheck(
      CreateMoveEntryOptionsProto(mount_id, source_path, target_path));
}

ProtoBlob CreateCopyEntryOptionsBlob(int32_t mount_id,
                                     const std::string& source_path,
                                     const std::string& target_path) {
  return SerializeProtoToBlobAndCheck(
      CreateCopyEntryOptionsProto(mount_id, source_path, target_path));
}

ProtoBlob CreateGetDeleteListOptionsBlob(int32_t mount_id,
                                         const std::string& entry_path) {
  return SerializeProtoToBlobAndCheck(
      CreateGetDeleteListOptionsProto(mount_id, entry_path));
}

ProtoBlob CreateGetSharesOptionsBlob(const std::string& server_url) {
  return SerializeProtoToBlobAndCheck(CreateGetSharesOptionsProto(server_url));
}

ProtoBlob CreateUpdateMountCredentialsOptionsBlob(int32_t mount_id,
                                                  const std::string& workgroup,
                                                  const std::string& username) {
  return SerializeProtoToBlobAndCheck(
      CreateUpdateMountCredentialsOptionsProto(mount_id, workgroup, username));
}

ProtoBlob CreateUpdateSharePathOptionsBlob(int32_t mount_id,
                                           const std::string& share_path) {
  return SerializeProtoToBlobAndCheck(
      CreateUpdateSharePathOptionsProto(mount_id, share_path));
}

base::ScopedFD WritePasswordToFile(TempFileManager* temp_manager,
                                   const std::string& password) {
  const size_t password_size = password.size();
  std::vector<uint8_t> password_data(sizeof(password_size) + password.size());

  // Write the password length in the first sizeof(size_t) bytes of the buffer.
  std::memcpy(password_data.data(), &password_size, sizeof(password_size));

  // Append |password| starting at the end of password_size.
  std::memcpy(password_data.data() + sizeof(password_size), password.c_str(),
              password.size());

  return temp_manager->CreateTempFile(password_data);
}

std::string CreateKrb5ConfPath(const base::FilePath& temp_dir) {
  return temp_dir.Append(kTestKrb5ConfName).value();
}

std::string CreateKrb5CCachePath(const base::FilePath& temp_dir) {
  return temp_dir.Append(kTestCCacheName).value();
}

void ExpectFileEqual(const std::string& path,
                     const std::string expected_contents) {
  const base::FilePath file_path(path);
  std::string actual_contents;
  EXPECT_TRUE(ReadFileToString(file_path, &actual_contents));

  EXPECT_EQ(expected_contents, actual_contents);
}

void ExpectFileNotEqual(const std::string& path,
                        const std::string expected_contents) {
  const base::FilePath file_path(path);
  std::string actual_contents;
  EXPECT_TRUE(ReadFileToString(file_path, &actual_contents));

  EXPECT_NE(expected_contents, actual_contents);
}

void ExpectCredentialsEqual(MountManager* mount_manager,
                            int32_t mount_id,
                            const std::string& root_path,
                            const std::string& workgroup,
                            const std::string& username,
                            const std::string& password) {
  DCHECK(mount_manager);

  constexpr size_t kComparisonBufferSize = 256;
  char workgroup_buffer[kComparisonBufferSize];
  char username_buffer[kComparisonBufferSize];
  char password_buffer[kComparisonBufferSize];

  SambaInterface* samba_interface;
  EXPECT_TRUE(mount_manager->GetSambaInterface(mount_id, &samba_interface));

  const SambaInterface::SambaInterfaceId samba_interface_id =
      samba_interface->GetSambaInterfaceId();

  EXPECT_TRUE(mount_manager->GetAuthentication(
      samba_interface_id, root_path, workgroup_buffer, kComparisonBufferSize,
      username_buffer, kComparisonBufferSize, password_buffer,
      kComparisonBufferSize));

  EXPECT_EQ(std::string(workgroup_buffer), workgroup);
  EXPECT_EQ(std::string(username_buffer), username);
  EXPECT_EQ(std::string(password_buffer), password);
}

std::vector<uint8_t> CreateNetBiosResponsePacket(
    const std::vector<std::vector<uint8_t>>& hostnames,
    uint8_t name_length,
    std::vector<uint8_t> name,
    uint16_t transaction_id,
    uint8_t response_type) {
  // Build the prefix of the packet.
  std::vector<uint8_t> packet = {0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  // Set Transaction ID in Big Endian representation.
  packet[0] = transaction_id >> 8;
  packet[1] = transaction_id & 0xFF;

  // Add the name section.
  packet.push_back(name_length);
  packet.insert(packet.end(), name.begin(), name.end());

  // Add the next section
  std::vector<uint8_t> middle_section = {0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
                                         0x00, 0x00, 0x00, 0x00, 0x00};
  // Set the response_type.
  middle_section[2] = response_type;

  packet.insert(packet.end(), middle_section.begin(), middle_section.end());

  // Set number of address list entries.
  packet.push_back(hostnames.size());

  // Add the address list entries.
  for (const auto& hostname : hostnames) {
    packet.insert(packet.end(), hostname.begin(), hostname.end());
  }

  return packet;
}

std::vector<uint8_t> CreateNetBiosResponsePacket(
    const std::vector<std::vector<uint8_t>>& hostnames,
    std::vector<uint8_t> name,
    uint16_t transaction_id,
    uint8_t response_type) {
  return CreateNetBiosResponsePacket(hostnames, name.size(), name,
                                     transaction_id, response_type);
}

std::vector<uint8_t> CreateValidNetBiosHostname(const std::string& hostname,
                                                uint8_t type) {
  DCHECK_LE(hostname.size(), netbios::kServerNameLength);

  std::vector<uint8_t> hostname_bytes(netbios::kServerEntrySize);
  std::copy(hostname.begin(), hostname.end(), hostname_bytes.begin());

  // Fill the rest of the name with spaces.
  std::fill(hostname_bytes.begin() + hostname.size(),
            hostname_bytes.begin() + netbios::kServerNameLength, 0x20);

  // Set the type.
  hostname_bytes[15] = type;

  // Set two nulls for the flags.
  hostname_bytes[16] = 0x00;
  hostname_bytes[17] = 0x00;

  return hostname_bytes;
}

}  // namespace smbprovider
