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

#include <fuchsia/device/llcpp/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/syslog/cpp/macros.h>

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

namespace isolated_devmgr {

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};

static fidl::StringView FvmDriverLib() { return fidl::StringView("/pkg/bin/driver/fvm.so"); }

zx::status<std::string> CreateFvmInstance(const std::string& device_path, int 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(fvm_init(fd.get(), slice_size));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Could not format disk with FVM";
    return status.take_error();
  }
  zx::channel fvm_channel;
  status = zx::make_status(fdio_get_service_handle(fd.get(), fvm_channel.reset_and_get_address()));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Could not convert fd to channel";
    return status.take_error();
  }
  auto resp = llcpp::fuchsia::device::Controller::Call::Bind(zx::unowned_channel(fvm_channel.get()),
                                                             FvmDriverLib());
  status = zx::make_status(resp.status());
  if (status.is_ok()) {
    if (resp->result.is_err()) {
      status = zx::make_status(resp->result.err());
    }
  }
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Could not bind disk to FVM driver";
    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, int slice_size) {
  // 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;
  memset(&request, 0, sizeof(request));
  request.slice_count = 1;
  strcpy(request.name, "fs-test-partition");
  memcpy(request.type, kTestPartGUID, sizeof(request.type));
  memcpy(request.guid, kTestUniqueGUID, sizeof(request.guid));

  fbl::unique_fd fd(fvm_allocate_partition(fvm_fd.get(), &request));
  if (!fd) {
    FX_LOGS(ERROR) << "Could not allocate FVM partition";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  close(fvm_fd.release());

  char partition_path[PATH_MAX];
  fd.reset(open_partition(kTestUniqueGUID, kTestPartGUID, 0, partition_path));
  if (!fd) {
    FX_LOGS(ERROR) << "Could not locate FVM partition";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  return zx::ok(partition_path);
}

}  // namespace isolated_devmgr
