// Copyright 2019 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_daemon.h"

#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>

#include <utility>

#include <base/bind.h>
#include <base/check.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/no_destructor.h>
#include <base/notreached.h>
#include <base/threading/thread_task_runner_handle.h>
#include <brillo/message_loops/message_loop.h>
#include <brillo/daemons/dbus_daemon.h>
#include <chromeos/dbus/service_constants.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/public/cpp/platform/platform_channel.h>
#include <mojo/public/cpp/system/invitation.h>

#include "smbfs/dbus-proxies.h"
#include "smbfs/fuse_session.h"
#include "smbfs/smb_filesystem.h"
#include "smbfs/smbfs.h"
#include "smbfs/test_filesystem.h"

namespace smbfs {
namespace {

constexpr char kSmbConfDir[] = ".smb";
constexpr char kSmbConfFile[] = "smb.conf";

constexpr char kSmbConfData[] = R"(
[global]
  client min protocol = SMB2
  client max protocol = SMB3
  security = user
)";

bool CreateDirectoryAndLog(const base::FilePath& path) {
  CHECK(path.IsAbsolute());
  base::File::Error error;
  bool success = base::CreateDirectoryAndGetError(path, &error);
  LOG_IF(ERROR, !success) << "Failed to create directory " << path.value()
                          << ": " << base::File::ErrorToString(error);
  return success;
}

// SmbFilesystem delegate that does nothing.
class NopSmbFilesystemDelegate : public SmbFilesystem::Delegate {
 public:
  NopSmbFilesystemDelegate() = default;
  ~NopSmbFilesystemDelegate() = default;

 private:
  // SmbFilesystem::Delegate overrides.:
  void RequestCredentials(RequestCredentialsCallback callback) override {
    // Respond with no null credentials, equivalent to the user canceling the
    // request dialog.
    std::move(callback).Run(nullptr);
  }
};

}  // namespace

SmbFsDaemon::SmbFsDaemon(fuse_chan* chan, const Options& options)
    : chan_(chan),
      use_test_fs_(options.use_test),
      share_path_(options.share_path),
      uid_(options.uid ? options.uid : getuid()),
      gid_(options.gid ? options.gid : getgid()),
      mojo_id_(options.mojo_id ? options.mojo_id : "") {
  DCHECK(chan_);
}

SmbFsDaemon::~SmbFsDaemon() = default;

int SmbFsDaemon::OnInit() {
  int ret = brillo::DBusDaemon::OnInit();
  if (ret != EX_OK) {
    return ret;
  }

  if (!SetupSmbConf()) {
    return EX_SOFTWARE;
  }

  if (!share_path_.empty()) {
    static base::NoDestructor<NopSmbFilesystemDelegate> dummy_delegate;
    SmbFilesystem::Options options;
    options.share_path = share_path_;
    options.uid = uid_;
    options.gid = gid_;
    options.allow_ntlm = true;
    std::unique_ptr<SmbFilesystem> fs = std::make_unique<SmbFilesystem>(
        dummy_delegate.get(), std::move(options));
    SmbFilesystem::ConnectError error = fs->EnsureConnected();
    if (error != SmbFilesystem::ConnectError::kOk) {
      LOG(ERROR) << "Unable to connect to SMB filesystem: " << error;
      return EX_SOFTWARE;
    }
    fs_ = std::move(fs);
  }

  return EX_OK;
}

int SmbFsDaemon::OnEventLoopStarted() {
  int ret = brillo::DBusDaemon::OnEventLoopStarted();
  if (ret != EX_OK) {
    return ret;
  }

  std::unique_ptr<Filesystem> fs;
  if (use_test_fs_) {
    fs = std::make_unique<TestFilesystem>(uid_, gid_);
  } else if (fs_) {
    fs = std::move(fs_);
  } else if (!mojo_id_.empty()) {
    if (!InitMojo()) {
      return EX_SOFTWARE;
    }
    return EX_OK;
  } else {
    NOTREACHED();
  }

  session_ = std::make_unique<FuseSession>(std::move(fs), chan_);
  chan_ = nullptr;
  if (!session_->Start(base::BindOnce(&Daemon::Quit, base::Unretained(this)))) {
    return EX_SOFTWARE;
  }

  return EX_OK;
}

bool SmbFsDaemon::SetupSmbConf() {
  // Create a temporary "home" directory where configuration files used by
  // libsmbclient will be placed.
  CHECK(temp_dir_.CreateUniqueTempDir());
  PCHECK(setenv("HOME", temp_dir_.GetPath().value().c_str(),
                1 /* overwrite */) == 0);
  LOG(INFO) << "Storing SMB configuration files in: "
            << temp_dir_.GetPath().value();

  bool success = CreateDirectoryAndLog(temp_dir_.GetPath().Append(kSmbConfDir));
  if (!success) {
    return false;
  }

  // TODO(amistry): Replace with smbc_setOptionProtocols() when Samba is
  // updated.
  return base::WriteFile(
             temp_dir_.GetPath().Append(kSmbConfDir).Append(kSmbConfFile),
             kSmbConfData, sizeof(kSmbConfData)) == sizeof(kSmbConfData);
}

bool SmbFsDaemon::InitMojo() {
  LOG(INFO) << "Boostrapping connection using Mojo";

  mojo::core::Init();
  ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
      base::ThreadTaskRunnerHandle::Get(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);

  mojo::PlatformChannel channel;

  // The SmbFs service is hosted in the browser, so is expected to
  // already be running when this starts. If this is not the case, the D-Bus
  // IPC below will fail and this process will shut down.
  org::chromium::SmbFsProxy dbus_proxy(bus_, kSmbFsServiceName);
  brillo::ErrorPtr error;
  if (!dbus_proxy.OpenIpcChannel(
          mojo_id_, channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD(),
          &error)) {
    return false;
  }

  mojo::IncomingInvitation invitation =
      mojo::IncomingInvitation::Accept(channel.TakeLocalEndpoint());
  mojo_session_ = std::make_unique<MojoSession>(
      bus_, temp_dir_.GetPath(), chan_,
      mojom::SmbFsBootstrapRequest(
          invitation.ExtractMessagePipe(mojom::kBootstrapPipeName)),
      uid_, gid_,
      base::BindOnce(&SmbFsDaemon::OnSessionShutdown, base::Unretained(this)));

  return true;
}

void SmbFsDaemon::OnSessionShutdown() {
  LOG(INFO) << "Mojo session shut down. Exiting.";
  QuitWithExitCode(EX_SOFTWARE);
}

}  // namespace smbfs
