// 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"

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
