// Copyright 2020 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.

#include "src/storage/blobfs/query.h"

#include <fuchsia/fs/llcpp/fidl.h>
#include <lib/fidl-async/cpp/bind.h>

#include "src/storage/blobfs/blobfs.h"
#include "src/storage/blobfs/format.h"
#include "src/storage/blobfs/runner.h"

using fuchsia_fs::wire::FilesystemInfoQuery;

namespace blobfs {

constexpr char kFsName[] = "blobfs";

QueryService::QueryService(async_dispatcher_t* dispatcher, Blobfs* blobfs, Runner* runner)
    : fs::Service([dispatcher, this](fidl::ServerEnd<fuchsia_fs::Query> server_end) {
        return fidl::BindSingleInFlightOnly(dispatcher, std::move(server_end), this);
      }),
      blobfs_(blobfs),
      runner_(runner) {}

void QueryService::GetInfo(GetInfoRequestView request, GetInfoCompleter::Sync& completer) {
  static_assert(sizeof(kFsName) < fuchsia_fs::wire::kMaxFsNameLength, "Blobfs name too long");

  fidl::FidlAllocator allocator;
  fuchsia_fs::wire::FilesystemInfo filesystem_info(allocator);

  if (request->query & FilesystemInfoQuery::kTotalBytes) {
    filesystem_info.set_total_bytes(allocator,
                                    blobfs_->Info().data_block_count * blobfs_->Info().block_size);
  }

  if (request->query & FilesystemInfoQuery::kUsedBytes) {
    filesystem_info.set_used_bytes(allocator,
                                   blobfs_->Info().alloc_block_count * blobfs_->Info().block_size);
  }

  if (request->query & FilesystemInfoQuery::kTotalNodes) {
    filesystem_info.set_total_nodes(allocator, blobfs_->Info().inode_count);
  }

  if (request->query & FilesystemInfoQuery::kUsedNodes) {
    filesystem_info.set_used_nodes(allocator, blobfs_->Info().alloc_inode_count);
  }

  if (request->query & FilesystemInfoQuery::kFsId) {
    zx::event fs_id;
    zx_status_t status = blobfs_->GetFsId(&fs_id);
    if (status != ZX_OK) {
      completer.ReplyError(status);
      return;
    }
    filesystem_info.set_fs_id(allocator, std::move(fs_id));
  }

  if (request->query & FilesystemInfoQuery::kBlockSize) {
    filesystem_info.set_block_size(allocator, kBlobfsBlockSize);
  }

  if (request->query & FilesystemInfoQuery::kMaxNodeNameSize) {
    filesystem_info.set_max_node_name_size(allocator, digest::kSha256HexLength);
  }

  if (request->query & FilesystemInfoQuery::kFsType) {
    filesystem_info.set_fs_type(allocator, fuchsia_fs::wire::FsType::kBlobfs);
  }

  if (request->query & FilesystemInfoQuery::kName) {
    fidl::StringView name(kFsName);
    filesystem_info.set_name(allocator, std::move(name));
  }

  char name_buf[fuchsia_io2::wire::kMaxPathLength];
  if (request->query & FilesystemInfoQuery::kDevicePath) {
    size_t name_len;
    zx_status_t status =
        blobfs_->Device()->GetDevicePath(fuchsia_io2::wire::kMaxPathLength, name_buf, &name_len);
    if (status != ZX_OK) {
      completer.ReplyError(status);
      return;
    }
    // It appears that the |name_len| returned by |GetDevicePath| includes a trailing NUL.
    ZX_ASSERT(name_buf[name_len - 1] == '\0');
    fidl::StringView device_path(name_buf, name_len - 1);
    filesystem_info.set_device_path(allocator, std::move(device_path));
  }

  completer.ReplySuccess(std::move(filesystem_info));
}

void QueryService::IsNodeInFilesystem(IsNodeInFilesystemRequestView request,
                                      IsNodeInFilesystemCompleter::Sync& completer) {
  completer.Reply(runner_->IsTokenAssociatedWithVnode(std::move(request->token)));
}

}  // namespace blobfs
