// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef __Fuchsia__
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/dispatcher.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#endif  // __Fuchsia__

#include "src/storage/f2fs/f2fs.h"

namespace f2fs {

// TODO: set .configurable to true when the feature is supported.
const MountOpt default_option[] = {
    {"background_gc_off", 1, false},
    {"disable_roll_forward", 0, true},
    {"discard", 1, true},
    {"no_heap", 1, false},
    {"nouser_xattr", 1, false},
    {"noacl", 1, false},
    {"disable_ext_identify", 0, true},
    {"inline_xattr", 0, false},
    {"inline_data", 1, true},
    {"inline_dentry", 1, true},
    {"active_logs", 6, true},
};

zx_status_t Mount(const MountOptions &options, std::unique_ptr<f2fs::Bcache> bc) {
#ifdef __Fuchsia__
  zx::channel outgoing_server = zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST));

  if (!outgoing_server.is_valid()) {
    FX_LOGS(ERROR) << "could not get startup handle to serve on";
    return ZX_ERR_BAD_STATE;
  }

  auto export_root = fidl::ServerEnd<fuchsia_io::Directory>(std::move(outgoing_server));

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  trace::TraceProviderWithFdio trace_provider(loop.dispatcher());

  auto on_unmount = [&loop]() {
    loop.Quit();
    FX_LOGS(INFO) << "[f2fs] Unmounted successfully";
  };

  auto fs_or = CreateFsAndRoot(options, loop.dispatcher(), std::move(bc), std::move(export_root),
                               std::move(on_unmount));
  if (fs_or.is_error()) {
    FX_LOGS(ERROR) << "failed to create filesystem object " << fs_or.status_string();
    return EXIT_FAILURE;
  }

  FX_LOGS(INFO) << "[f2fs] Mounted successfully";

  ZX_ASSERT(loop.Run() == ZX_ERR_CANCELED);

#else   // __Fuchsia__
  auto fs_or = CreateFsAndRoot(options, std::move(bc));
  if (fs_or.is_error()) {
    FX_LOGS(ERROR) << "failed to create filesystem object";
    return EXIT_FAILURE;
  }
#endif  // __Fuchsia__

  return ZX_OK;
}

MountOptions::MountOptions() {
  for (uint32_t i = 0; i < kOptMaxNum; ++i) {
    opt_[i] = default_option[i];
  }
}

zx_status_t MountOptions::GetValue(const uint32_t opt_id, uint32_t *out) {
  if (opt_id >= kOptMaxNum)
    return ZX_ERR_INVALID_ARGS;
  *out = opt_[opt_id].value;
  return ZX_OK;
}

uint32_t MountOptions::GetOptionID(std::string_view opt) {
  for (uint32_t i = 0; i < kOptMaxNum; ++i) {
    if (opt_[i].name.compare(opt) == 0) {
      return i;
    }
  }
  return kOptMaxNum;
}

zx_status_t MountOptions::SetValue(std::string_view opt, const uint32_t value) {
  zx_status_t ret = ZX_ERR_INVALID_ARGS;
  uint32_t id = GetOptionID(opt);
  if (id < kOptMaxNum && !opt_[id].configurable) {
    FX_LOGS(WARNING) << opt << " is not configurable.";
  } else {
    switch (id) {
      case kOptActiveLogs:
        if (value != 2 && value != 4 && value != 6) {
          FX_LOGS(WARNING) << opt << " can be set only to 2, 4, or 6.";
        } else {
          opt_[id].value = value;
          ret = ZX_OK;
        }
        break;
      case kOptDiscard:
      case kOptBgGcOff:
      case kOptNoHeap:
      case kOptDisableExtIdentify:
      case kOptNoUserXAttr:
      case kOptNoAcl:
      case kOptDisableRollForward:
      case kOptInlineXattr:
      case kOptInlineData:
      case kOptInlineDentry:
        opt_[id].value = value;
        ret = ZX_OK;
        break;
      default:
        FX_LOGS(WARNING) << opt << " is not supported.";
        break;
    };
  }
  return ret;
}

}  // namespace f2fs
