// 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 <sys/vfs.h>

#include <memory>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/message_loop/message_pump_type.h>
#include <base/posix/eintr_wrapper.h>
#include <base/threading/platform_thread.h>
#include <base/threading/thread.h>
#include <brillo/syslog_logging.h>

#include "virtual_file_provider/fuse_main.h"
#include "virtual_file_provider/service.h"
#include "virtual_file_provider/util.h"

namespace virtual_file_provider {

namespace {

// Service thread handles D-Bus method calls.
class ServiceThread : public base::Thread {
 public:
  ServiceThread(const base::FilePath& fuse_mount_path, SizeMap* size_map)
      : Thread("Service thread"),
        fuse_mount_path_(fuse_mount_path),
        service_(std::make_unique<Service>(fuse_mount_path, size_map)) {}

  ~ServiceThread() override { Stop(); }

  Service* service() { return service_.get(); }

 protected:
  // base::Thread overrides:
  void Init() override {
    CHECK(WaitForFuseMount());
    CHECK(ClearCapabilities());
    CHECK(service_->Initialize());
  }

  void CleanUp() override {
    service_.reset();  // Must be destructed on the same thread as Initialize().
  }

 private:
  // Waits for the FUSE mount to get ready.
  bool WaitForFuseMount() {
    constexpr int kMaxRetryCount = 3000;
    constexpr base::TimeDelta kRetryInterval =
        base::TimeDelta::FromMilliseconds(1);

    for (int retry_count = 0; retry_count < kMaxRetryCount; ++retry_count) {
      struct statfs buf = {};
      if (HANDLE_EINTR(statfs(fuse_mount_path_.value().c_str(), &buf)) < 0) {
        PLOG(ERROR) << "statfs() failed.";
        return false;
      }
      // Compare with FUSE_SUPER_MAGIC (defined in <kernel>/fs/fuse/inode.c).
      if (buf.f_type == 0x65735546)
        return true;

      base::PlatformThread::Sleep(kRetryInterval);
    }
    LOG(ERROR) << "Timed out while waiting for FUSE mount.";
    return false;
  }

  const base::FilePath fuse_mount_path_;
  std::unique_ptr<Service> service_;

  DISALLOW_COPY_AND_ASSIGN(ServiceThread);
};

class FuseMainDelegateImpl : public FuseMainDelegate {
 public:
  FuseMainDelegateImpl(ServiceThread* service_thread, SizeMap* size_map)
      : service_thread_(service_thread), size_map_(size_map) {}
  ~FuseMainDelegateImpl() override = default;

  // FuseMainDelegate overrides:
  int64_t GetSize(const std::string& id) override;
  void HandleReadRequest(const std::string& id,
                         int64_t offset,
                         int64_t size,
                         base::ScopedFD fd) override;
  void NotifyIdReleased(const std::string& id) override;

 private:
  ServiceThread* const service_thread_;
  SizeMap* const size_map_;

  DISALLOW_COPY_AND_ASSIGN(FuseMainDelegateImpl);
};

int64_t FuseMainDelegateImpl::GetSize(const std::string& id) {
  return size_map_->GetSize(id);
}

void FuseMainDelegateImpl::HandleReadRequest(const std::string& id,
                                             int64_t offset,
                                             int64_t size,
                                             base::ScopedFD fd) {
  service_thread_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&Service::SendReadRequest,
                 // This is safe as service_thread outlives the FUSE main loop.
                 base::Unretained(service_thread_->service()), id, offset, size,
                 base::Passed(&fd)));
}

void FuseMainDelegateImpl::NotifyIdReleased(const std::string& id) {
  if (!size_map_->Erase(id)) {
    LOG(ERROR) << "Invalid ID " << id;
    return;
  }
  service_thread_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&Service::SendIdReleased,
                 // This is safe as service_thread outlives the FUSE main loop.
                 base::Unretained(service_thread_->service()), id));
}

}  // namespace

}  // namespace virtual_file_provider

int main(int argc, char** argv) {
  if (argc != 2) {
    fprintf(stderr, "usage: %s <FUSE mount path>\n", argv[0]);
    return 1;
  }
  base::FilePath fuse_mount_path(argv[1]);

  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);
  base::AtExitManager at_exit_manager;

  virtual_file_provider::SizeMap size_map;

  // Run D-Bus service on the service thread.
  virtual_file_provider::ServiceThread service_thread(fuse_mount_path,
                                                      &size_map);
  base::Thread::Options options;
#if BASE_VER < 780000
  options.message_loop_type = base::MessageLoop::TYPE_IO;
#else
  options.message_pump_type = base::MessagePumpType::IO;
#endif
  service_thread.StartWithOptions(options);

  // Enter the FUSE main loop.
  virtual_file_provider::FuseMainDelegateImpl delegate(&service_thread,
                                                       &size_map);
  return virtual_file_provider::FuseMain(fuse_mount_path, &delegate);
}
