// Copyright 2020 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 "smbfs/smbfs_bootstrap_impl.h"

#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <mojo/public/cpp/system/platform_handle.h>

#include "smbfs/smb_credential.h"
#include "smbfs/smb_filesystem.h"
#include "smbfs/smbfs_impl.h"

namespace smbfs {
namespace {

mojom::MountError ConnectErrorToMountError(SmbFilesystem::ConnectError error) {
  switch (error) {
    case SmbFilesystem::ConnectError::kNotFound:
      return mojom::MountError::kNotFound;
    case SmbFilesystem::ConnectError::kAccessDenied:
      return mojom::MountError::kAccessDenied;
    case SmbFilesystem::ConnectError::kSmb1Unsupported:
      return mojom::MountError::kInvalidProtocol;
    default:
      return mojom::MountError::kUnknown;
  }
}

std::unique_ptr<password_provider::Password> MakePasswordFromMojoHandle(
    mojo::ScopedHandle handle, int32_t length) {
  base::ScopedFD fd = mojo::UnwrapPlatformHandle(std::move(handle)).TakeFD();
  return password_provider::Password::CreateFromFileDescriptor(fd.get(),
                                                               length);
}

}  // namespace

SmbFsBootstrapImpl::SmbFsBootstrapImpl(mojom::SmbFsBootstrapRequest request,
                                       Delegate* delegate)
    : binding_(this, std::move(request)), delegate_(delegate) {
  DCHECK(delegate_);
  binding_.set_connection_error_handler(base::Bind(
      &Delegate::OnBootstrapConnectionError, base::Unretained(delegate)));
}

SmbFsBootstrapImpl::~SmbFsBootstrapImpl() = default;

void SmbFsBootstrapImpl::MountShare(mojom::MountOptionsPtr options,
                                    mojom::SmbFsDelegatePtr smbfs_delegate,
                                    const MountShareCallback& callback) {
  if (options->share_path.find("smb://") != 0) {
    // TODO(amistry): More extensive URL validation.
    LOG(ERROR) << "Invalid share path: " << options->share_path;
    callback.Run(mojom::MountError::kInvalidUrl, nullptr);
    return;
  }

  std::unique_ptr<SmbCredential> credential = std::make_unique<SmbCredential>(
      options->workgroup, options->username, nullptr);
  if (options->kerberos_config) {
    delegate_->SetupKerberos(
        std::move(options->kerberos_config),
        base::BindOnce(&SmbFsBootstrapImpl::OnCredentialsSetup,
                       base::Unretained(this), std::move(options),
                       std::move(smbfs_delegate), callback,
                       std::move(credential), true /* use_kerberos */));
    return;
  }

  if (options->password) {
    credential->password = MakePasswordFromMojoHandle(
        std::move(options->password->fd), options->password->length);
  }

  OnCredentialsSetup(std::move(options), std::move(smbfs_delegate), callback,
                     std::move(credential), false /* use_kerberos */,
                     true /* setup_success */);
}

void SmbFsBootstrapImpl::OnCredentialsSetup(
    mojom::MountOptionsPtr options,
    mojom::SmbFsDelegatePtr smbfs_delegate,
    const MountShareCallback& callback,
    std::unique_ptr<SmbCredential> credential,
    bool use_kerberos,
    bool setup_success) {
  if (!setup_success) {
    callback.Run(mojom::MountError::kUnknown, nullptr);
    return;
  }

  auto fs = delegate_->CreateSmbFilesystem(options->share_path,
                                           std::move(credential));
  // Don't use the resolved address if Kerberos is set up. Kerberos requires the
  // full hostname to obtain auth tickets.
  if (options->resolved_host && !use_kerberos) {
    if (options->resolved_host->address_bytes.size() != 4) {
      LOG(ERROR) << "Invalid IP address size: "
                 << options->resolved_host->address_bytes.size();
      callback.Run(mojom::MountError::kInvalidOptions, nullptr);
      return;
    }
    fs->SetResolvedAddress(options->resolved_host->address_bytes);
  }
  if (!options->skip_connect) {
    SmbFilesystem::ConnectError error = fs->EnsureConnected();
    if (error != SmbFilesystem::ConnectError::kOk) {
      LOG(ERROR) << "Unable to connect to SMB share " << options->share_path
                 << ": " << error;
      callback.Run(ConnectErrorToMountError(error), nullptr);
      return;
    }
  }

  mojom::SmbFsPtr smbfs_ptr;
  fs->SetSmbFsImpl(std::make_unique<SmbFsImpl>(
      fs.get(), std::move(smbfs_delegate), mojo::MakeRequest(&smbfs_ptr)));

  if (!delegate_->StartFuseSession(std::move(fs))) {
    callback.Run(mojom::MountError::kUnknown, nullptr);
    return;
  }

  callback.Run(mojom::MountError::kOk, std::move(smbfs_ptr));
}

}  // namespace smbfs
