// 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_helper.h"

#include <errno.h>
#include <string.h>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_piece.h>
#include <libsmbclient.h>

#include "smbprovider/constants.h"
#include "smbprovider/proto.h"

namespace smbprovider {

std::string AppendPath(const std::string& base_path,
                       const std::string& relative_path) {
  const base::FilePath path(base_path);
  base::FilePath relative(relative_path);
  if (relative.IsAbsolute() && relative_path.size() > 0) {
    // Remove the beginning "/" since FilePath#Append() cannot append an
    // 'absolute' path.
    relative = base::FilePath(
        base::StringPiece(relative_path.c_str() + 1, relative_path.size() - 1));
  }
  return path.Append(relative).value();
}

bool IsSelfOrParentDir(const std::string& entry_name) {
  return entry_name == kEntrySelf || entry_name == kEntryParent;
}

bool IsFileOrDir(uint32_t smbc_type) {
  return smbc_type == SMBC_FILE || smbc_type == SMBC_DIR;
}

bool IsSmbShare(uint32_t smbc_type) {
  return smbc_type == SMBC_FILE_SHARE;
}

bool IsSymlink(uint16_t file_attrs) {
  return file_attrs & kFileAttributeReparsePoint;
}

ErrorType GetErrorFromErrno(int32_t error_code) {
  DCHECK_GT(error_code, 0);
  switch (error_code) {
    case EPERM:
    case EACCES:
      return ERROR_ACCESS_DENIED;
    case ENOENT:
      return ERROR_NOT_FOUND;
    case EMFILE:
    case ENFILE:
      return ERROR_TOO_MANY_OPENED;
    case ENOTDIR:
      return ERROR_NOT_A_DIRECTORY;
    case EISDIR:
      return ERROR_NOT_A_FILE;
    case ENOTEMPTY:
      return ERROR_NOT_EMPTY;
    case EEXIST:
      return ERROR_EXISTS;
    case EINVAL:
      return ERROR_INVALID_OPERATION;
    case ECONNABORTED:
      return ERROR_SMB1_UNSUPPORTED;
    case EBADF:
    case ENODEV:
    case ETIMEDOUT:
      return ERROR_OPERATION_FAILED;
    default:
      LOG(WARNING) << "Unexpected error code " << error_code << ": "
                   << strerror(error_code);
      return ERROR_FAILED;
  }
}

// EINVAL is returned when Samba is unable to parse a hostname
// (eg. \\qnap\testshare). This problem is rooted in Samba, a proper fix would
// be to patch the Samba library.
ErrorType GetErrorFromErrnoForReadDir(int32_t error_code) {
  if (error_code == EINVAL) {
    return ERROR_NOT_FOUND;
  }

  return GetErrorFromErrno(error_code);
}

bool IsDirectory(const struct stat& stat_info) {
  return S_ISDIR(stat_info.st_mode);
}

bool IsFile(const struct stat& stat_info) {
  return S_ISREG(stat_info.st_mode);
}

void LogAndSetError(const char* operation_name,
                    int32_t mount_id,
                    ErrorType error_received,
                    int32_t* error_code) {
  LogOperationError(operation_name, mount_id, error_received);
  *error_code = static_cast<int32_t>(error_received);
}

void LogOperationError(const char* operation_name,
                       int32_t mount_id,
                       ErrorType error_received) {
  LOG(ERROR) << "Cannot " << operation_name << " on Mount [" << mount_id
             << "]: " << error_received;
}

void LogAndSetDBusParseError(const char* operation_name, int32_t* error_code) {
  LogAndSetError(operation_name, -1, ERROR_DBUS_PARSE_FAILED, error_code);
}

int32_t GetDirectoryEntryProtoFromStat(const std::string& full_path,
                                       const struct stat& stat_info,
                                       ProtoBlob* proto_blob) {
  DCHECK(proto_blob);
  bool is_directory = IsDirectory(stat_info);
  int64_t size = is_directory ? 0 : stat_info.st_size;
  const base::FilePath path(full_path);

  DirectoryEntryProto entry;
  entry.set_is_directory(is_directory);
  entry.set_name(path.BaseName().value());
  entry.set_size(size);
  entry.set_last_modified_time(stat_info.st_mtime);
  return static_cast<int32_t>(SerializeProtoToBlob(entry, proto_blob));
}

bool IsValidOpenFileFlags(int32_t flags) {
  return flags == O_RDONLY || flags == O_RDWR || flags == O_WRONLY;
}

bool ReadFromFD(const WriteFileOptionsProto& options,
                const base::ScopedFD& fd,
                int32_t* error,
                std::vector<uint8_t>* buffer) {
  DCHECK(buffer);
  DCHECK(error);

  if (!fd.is_valid()) {
    LogAndSetError(options, ERROR_DBUS_PARSE_FAILED, error);
    return false;
  }

  buffer->resize(options.length());
  if (!base::ReadFromFD(fd.get(), reinterpret_cast<char*>(buffer->data()),
                        buffer->size())) {
    LogAndSetError(options, ERROR_IO, error);
    return false;
  }

  return true;
}

int32_t GetOpenFilePermissions(const bool writeable) {
  return writeable ? O_RDWR : O_RDONLY;
}

int32_t GetOpenFilePermissions(const OpenFileOptionsProto& options) {
  return GetOpenFilePermissions(options.writeable());
}

int32_t GetOpenFilePermissions(const TruncateOptionsProto& unused) {
  return O_WRONLY;
}

int32_t GetOpenFilePermissions(const CopyEntryOptionsProto& unused) {
  // OpenFile is Read-Only for CopyEntry since we only need to read the source.
  return O_RDONLY;
}

PathParts SplitPath(const std::string& full_path) {
  DCHECK(!full_path.empty());
  base::FilePath path(full_path);
  std::vector<std::string> result;
  path.GetComponents(&result);
  return result;
}

std::string RemoveURLScheme(const std::string& smb_url) {
  DCHECK_EQ(0, smb_url.compare(0, 6, kSmbUrlScheme));
  return smb_url.substr(5, std::string::npos);
}

std::string GetFileName(const std::string& full_path) {
  base::FilePath file_path(RemoveURLScheme(full_path));
  return file_path.BaseName().value();
}

std::string GetDirPath(const std::string& full_path) {
  std::string path = RemoveURLScheme(full_path);
  return base::FilePath(path).DirName().value();
}

bool ShouldReportCreateDirError(int32_t result, bool ignore_existing) {
  if (result == 0) {
    return false;
  }
  return !(result == EEXIST && ignore_existing);
}

std::ostream& operator<<(std::ostream& out, const ErrorType error) {
  switch (error) {
    case ERROR_NONE:
      return out << "ERROR_NONE";
    case ERROR_OK:
      return out << "ERROR_OK";
    case ERROR_FAILED:
      return out << "ERROR_FAILED";
    case ERROR_IN_USE:
      return out << "ERROR_IN_USE";
    case ERROR_EXISTS:
      return out << "ERROR_EXISTS";
    case ERROR_NOT_FOUND:
      return out << "ERROR_NOT_FOUND";
    case ERROR_ACCESS_DENIED:
      return out << "ERROR_ACCESS_DENIED";
    case ERROR_TOO_MANY_OPENED:
      return out << "ERROR_TOO_MANY_OPENED";
    case ERROR_NO_MEMORY:
      return out << "ERROR_NO_MEMORY";
    case ERROR_NO_SPACE:
      return out << "ERROR_NO_SPACE";
    case ERROR_NOT_A_DIRECTORY:
      return out << "ERROR_NOT_A_DIRECTORY";
    case ERROR_INVALID_OPERATION:
      return out << "ERROR_INVALID_OPERATION";
    case ERROR_SECURITY:
      return out << "ERROR_SECURITY";
    case ERROR_ABORT:
      return out << "ERROR_ABORT";
    case ERROR_NOT_A_FILE:
      return out << "ERROR_NOT_A_FILE";
    case ERROR_NOT_EMPTY:
      return out << "ERROR_NOT_EMPTY";
    case ERROR_INVALID_URL:
      return out << "ERROR_INVALID_URL";
    case ERROR_IO:
      return out << "ERROR_IO";
    case ERROR_PROVIDER_ERROR_COUNT:
      return out << "ERROR_PROVIDER_ERROR_COUNT";
    case ERROR_DBUS_PARSE_FAILED:
      return out << "ERROR_DBUS_PARSE_FAILED";
    case ERROR_COPY_PENDING:
      return out << "ERROR_COPY_PENDING";
    case ERROR_COPY_FAILED:
      return out << "ERROR_COPY_FAILED";
    case ERROR_SMB1_UNSUPPORTED:
      return out << "ERROR_SMB1_UNSUPPORTED";
    case ERROR_OPERATION_PENDING:
      return out << "ERROR_OPERATION_PENDING";
    case ERROR_OPERATION_FAILED:
      return out << "ERROR_OPERATION_FAILED";
    default:
      return out << "ERROR_"
                 << static_cast<std::underlying_type_t<ErrorType>>(error);
  }
}

}  // namespace smbprovider
