// 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/testing/fvm.h"

#include <fcntl.h>
#include <fidl/fuchsia.device/cpp/wire.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/fdio.h>
#include <lib/syslog/cpp/macros.h>

#include <fbl/unique_fd.h>
#include <ramdevice-client/ramdisk.h>

#include "src/lib/storage/fs_management/cpp/fvm.h"

namespace storage {

constexpr uint8_t kTestPartGUID[] = {0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                                     0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

constexpr uint8_t kTestUniqueGUID[] = {0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

zx::status<> BindFvm(int fd) {
  fdio_cpp::UnownedFdioCaller caller(fd);
  auto resp = fidl::WireCall(caller.borrow_as<fuchsia_device::Controller>())->Bind("fvm.so");
  auto status = zx::make_status(resp.status());
  if (status.is_ok()) {
    if (resp->is_error()) {
      status = zx::make_status(resp->error_value());
    }
  }
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Could not bind disk to FVM driver";
    return status.take_error();
  }
  return zx::ok();
}

zx::status<std::string> CreateFvmInstance(const std::string& device_path, size_t slice_size) {
  fbl::unique_fd fd(open(device_path.c_str(), O_RDWR));
  if (!fd) {
    FX_LOGS(ERROR) << "Could not open test disk";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  auto status = zx::make_status(fs_management::FvmInit(fd.get(), slice_size));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Could not format disk with FVM";
    return status.take_error();
  }
  status = BindFvm(fd.get());
  if (status.is_error())
    return status.take_error();
  std::string fvm_disk_path = device_path + "/fvm";
  status = zx::make_status(wait_for_device(fvm_disk_path.c_str(), zx::sec(3).get()));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "FVM driver never appeared at " << fvm_disk_path;
    return status.take_error();
  }

  return zx::ok(fvm_disk_path);
}

zx::status<std::string> CreateFvmPartition(const std::string& device_path, size_t slice_size,
                                           const FvmOptions& options) {
  if (options.name.size() >= BLOCK_NAME_LEN)
    return zx::error(ZX_ERR_INVALID_ARGS);

  // Format the raw device to support FVM, and bind the FVM driver to it.
  zx::status<std::string> fvm_disk_path_or = CreateFvmInstance(device_path, slice_size);
  if (fvm_disk_path_or.is_error()) {
    return fvm_disk_path_or.take_error();
  }

  // Open "fvm" driver
  auto fvm_fd = fbl::unique_fd(open(fvm_disk_path_or->c_str(), O_RDWR));
  if (!fvm_fd) {
    FX_LOGS(ERROR) << "Could not open FVM driver: errno=" << errno;
    return zx::error(ZX_ERR_BAD_STATE);
  }

  alloc_req_t request = {.slice_count = options.initial_fvm_slice_count};
  memcpy(request.name, options.name.data(), options.name.size());
  request.name[options.name.size()] = 0;
  memcpy(request.type, options.type ? options.type->data() : kTestPartGUID, sizeof(request.type));
  memcpy(request.guid, kTestUniqueGUID, sizeof(request.guid));

  if (auto fd_or = fs_management::FvmAllocatePartition(fvm_fd.get(), &request); fd_or.is_error()) {
    FX_LOGS(ERROR) << "Could not allocate FVM partition (slice count: "
                   << options.initial_fvm_slice_count << ")";
    return fd_or.take_error();
  }
  fvm_fd.reset();

  std::string partition_path;
  fs_management::PartitionMatcher matcher{
      .type_guid = request.type,
      .instance_guid = kTestUniqueGUID,
  };
  if (auto fd_or = fs_management::OpenPartition(&matcher, 0, &partition_path); fd_or.is_error()) {
    FX_LOGS(ERROR) << "Could not locate FVM partition";
    return fd_or.take_error();
  }
  return zx::ok(partition_path);
}

}  // namespace storage
