// Copyright 2019 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 "mbr-device.h"

#include <fuchsia/hardware/block/c/banjo.h>
#include <fuchsia/hardware/block/partition/c/banjo.h>
#include <inttypes.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/ddk/driver.h>
#include <lib/sync/completion.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/hw/gpt.h>
#include <zircon/status.h>
#include <zircon/threads.h>
#include <zircon/types.h>

#include <algorithm>
#include <memory>
#include <utility>

#include <fbl/alloc_checker.h>
#include <fbl/string.h>
#include <fbl/vector.h>
#include <gpt/c/gpt.h>

#include "mbr.h"
#include "src/devices/block/drivers/mbr/mbr_bind.h"

namespace {

// ATTN: MBR supports 8 bit partition types instead of GUIDs. Here we define
// mappings between partition type and GUIDs that zircon understands. When
// the MBR driver receives a request for the type GUID, we lie and return the
// a mapping from partition type to type GUID.
const uint8_t kDataGuid[GPT_GUID_LEN] = GUID_DATA_VALUE;
const uint8_t kSysGuid[GPT_GUID_LEN] = GUID_SYSTEM_VALUE;
const uint8_t kMicrosoftDataGuid[GPT_GUID_LEN] = GPT_MICROSOFT_BASIC_DATA_TYPE_GUID;

const uint8_t kSupportedPartitionTypes[] = {
    mbr::kPartitionTypeFuchsiaData, mbr::kPartitionTypeFuchsiaSys, mbr::kPartitionTypeFat12,
    mbr::kPartitionTypeFat16,       mbr::kPartitionTypeFat16B,     mbr::kPartitionTypeFat16LBA,
    mbr::kPartitionTypeFat32,       mbr::kPartitionTypeFat32LBA,
};

constexpr uint32_t DivRoundUp(uint32_t n, uint32_t d) { return (n + (d - 1)) / d; }

zx_status_t MbrReadHeader(const ddk::BlockProtocolClient& parent_proto, mbr::Mbr* mbr_out,
                          block_info_t* block_info_out, size_t* block_op_size_out) {
  parent_proto.Query(block_info_out, block_op_size_out);

  fbl::AllocChecker ac;
  std::unique_ptr<char[]> raw(new (&ac) char[*block_op_size_out]);
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }
  auto* bop = reinterpret_cast<block_op_t*>(raw.get());

  // We need to read at least 512B to parse the MBR. Determine if we should
  // read the device's block size or we should ready exactly 512B.
  uint32_t iosize = 0;
  if (block_info_out->block_size >= mbr::kMbrSize) {
    iosize = block_info_out->block_size;
  } else {
    // Make sure we're reading some multiple of the block size.
    iosize = DivRoundUp(mbr::kMbrSize, block_info_out->block_size) * block_info_out->block_size;
  }

  zx::vmo vmo;
  auto status = zx::vmo::create(iosize, 0, &vmo);
  if (status != ZX_OK) {
    zxlogf(ERROR, "mbr: cannot allocate vmo: %s", zx_status_get_string(status));
    return status;
  }

  sync_completion_t read_complete;

  bop->command = BLOCK_OP_READ;
  bop->rw.vmo = vmo.get();
  bop->rw.length = iosize / block_info_out->block_size;
  bop->rw.offset_dev = 0;
  bop->rw.offset_vmo = 0;

  zxlogf(TRACE, "mbr: Reading header from parent block device");

  parent_proto.Queue(
      bop,
      [](void* cookie, zx_status_t status, block_op_t* bop) {
        bop->command = status;
        sync_completion_signal(static_cast<sync_completion_t*>(cookie));
      },
      &read_complete);
  sync_completion_wait(&read_complete, ZX_TIME_INFINITE);

  if ((status = bop->command) != ZX_OK) {
    zxlogf(ERROR, "mbr: could not read mbr from device: %s", zx_status_get_string(status));
    return status;
  }

  uint8_t buffer[mbr::kMbrSize];
  if ((status = vmo.read(buffer, 0, sizeof(buffer))) != ZX_OK) {
    zxlogf(ERROR, "mbr: Failed to read MBR header: %s", zx_status_get_string(status));
    return status;
  }

  if ((status = mbr::Parse(buffer, sizeof(buffer), mbr_out)) != ZX_OK) {
    zxlogf(ERROR, "mbr: Failed to parse MBR: %s", zx_status_get_string(status));
    return status;
  }
  return ZX_OK;
}

}  // namespace

namespace mbr {

bool MbrDevice::SupportsPartitionType(uint8_t partition_type) {
  return std::end(kSupportedPartitionTypes) != std::find(std::begin(kSupportedPartitionTypes),
                                                         std::end(kSupportedPartitionTypes),
                                                         partition_type);
}

void MbrDevice::BlockImplQuery(block_info_t* info_out, size_t* block_op_size_out) {
  *info_out = info_;
  *block_op_size_out = block_op_size_;
}

void MbrDevice::BlockImplQueue(block_op_t* operation, block_impl_queue_callback completion_cb,
                               void* cookie) {
  switch (operation->command & BLOCK_OP_MASK) {
    case BLOCK_OP_READ:
    case BLOCK_OP_WRITE: {
      size_t blocks = operation->rw.length;
      size_t max = partition_.num_sectors;

      // Ensure that the request is in-bounds
      if ((operation->rw.offset_dev >= max) || ((max - operation->rw.offset_dev) < blocks)) {
        completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, operation);
        return;
      }

      // Adjust for partition starting block
      operation->rw.offset_dev += partition_.start_sector_lba;
      break;
    }
    case BLOCK_OP_FLUSH:
      break;
    default:
      completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, operation);
      return;
  }

  parent_protocol_.Queue(operation, completion_cb, cookie);
}

zx_status_t MbrDevice::BlockPartitionGetGuid(guidtype_t guid_type, guid_t* out_guid) {
  if (guid_type != GUIDTYPE_TYPE) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  switch (partition_.type) {
    case kPartitionTypeFuchsiaData: {
      memcpy(out_guid, kDataGuid, BLOCK_GUID_LEN);
      return ZX_OK;
    }
    case kPartitionTypeFuchsiaSys: {
      memcpy(out_guid, kSysGuid, BLOCK_GUID_LEN);
      return ZX_OK;
    }
    case kPartitionTypeFat12:
    case kPartitionTypeFat16:
    case kPartitionTypeFat16B:
    case kPartitionTypeFat16LBA:
    case kPartitionTypeFat32:
    case kPartitionTypeFat32LBA: {
      memcpy(out_guid, kMicrosoftDataGuid, BLOCK_GUID_LEN);
      return ZX_OK;
    }
    default: {
      zxlogf(ERROR, "mbr: Partition type 0x%02x unsupported", partition_.type);
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
}

zx_status_t MbrDevice::BlockPartitionGetName(char* out_name, size_t capacity) {
  if (capacity < GPT_NAME_LEN) {
    return ZX_ERR_BUFFER_TOO_SMALL;
  }
  strlcpy(out_name, name_.c_str(), capacity);
  return ZX_OK;
}

void MbrDevice::DdkUnbind(ddk::UnbindTxn txn) { txn.Reply(); }

void MbrDevice::DdkRelease() { delete this; }

zx_off_t MbrDevice::DdkGetSize() {
  // TODO: use query() results, *but* fvm returns different query and getsize
  // results, and the latter are dynamic...
  return device_get_size(parent_);
}

zx_status_t MbrDevice::DdkGetProtocol(uint32_t proto_id, void* out) {
  auto* proto = static_cast<ddk::AnyProtocol*>(out);
  switch (proto_id) {
    case ZX_PROTOCOL_BLOCK_IMPL: {
      proto->ops = &block_impl_protocol_ops_;
      proto->ctx = this;
      return ZX_OK;
    }
    case ZX_PROTOCOL_BLOCK_PARTITION: {
      proto->ops = &block_partition_protocol_ops_;
      proto->ctx = this;
      return ZX_OK;
    }
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }
}

zx_status_t MbrDevice::Create(zx_device_t* parent,
                              fbl::Vector<std::unique_ptr<MbrDevice>>* devices_out) {
  if (parent == nullptr || devices_out == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  ddk::BlockProtocolClient parent_proto(parent);
  if (!parent_proto.is_valid()) {
    zxlogf(ERROR, "mbr: ERROR: Parent device '%s' does not support ZX_PROTOCOL_BLOCK",
           device_get_name(parent));
    return ZX_ERR_NOT_SUPPORTED;
  }

  Mbr mbr;
  block_info_t block_info;
  size_t block_op_size;
  zx_status_t status;
  if ((status = MbrReadHeader(parent_proto, &mbr, &block_info, &block_op_size)) != ZX_OK) {
    return status;
  }

  // Parse the partitions out of the MBR.
  fbl::AllocChecker ac;
  for (unsigned i = 0; i < countof(mbr.partitions); ++i) {
    const auto& entry = mbr.partitions[i];
    if (entry.type == kPartitionTypeNone) {
      // This partition entry is empty and does not refer to a partition, skip it.
      continue;
    }

    if (entry.type == kPartitionTypeGptProtective && i == 0) {
      // If the first partition on the disk has type '0xee', this MBR is not a real MBR,
      // and we should refuse to bind to it.
      return ZX_ERR_NOT_SUPPORTED;
    }

    zxlogf(INFO, "mbr: found partition, entry = %d, type = 0x%02X, start = %u, length = 0x%X",
           i + 1, entry.type, entry.start_sector_lba, entry.num_sectors);

    if (!MbrDevice::SupportsPartitionType(entry.type)) {
      zxlogf(WARNING, "mbr: Not mounting partition %d, unsupported type 0x%02x", i, entry.type);
      continue;
    }

    char name[16];
    snprintf(name, sizeof(name), "part-%03u", i);

    block_info_t info = block_info;
    info.block_count = entry.num_sectors;

    auto device =
        fbl::make_unique_checked<MbrDevice>(&ac, parent, name, entry, info, block_op_size);
    if (!ac.check()) {
      zxlogf(ERROR, "mbr: Failed to allocate partition device");
      return ZX_ERR_NO_MEMORY;
    }

    devices_out->push_back(std::move(device), &ac);
    if (!ac.check()) {
      zxlogf(ERROR, "mbr: Failed to allocate partition device");
      return ZX_ERR_NO_MEMORY;
    }
  }
  return ZX_OK;
}

zx_status_t MbrDevice::Bind(std::unique_ptr<MbrDevice> device) {
  if (device.get() == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zx_status_t status;
  if ((status = device->DdkAdd(device->Name().c_str())) != ZX_OK) {
    zxlogf(ERROR, "mbr: Failed to add partition device: %s", zx_status_get_string(status));
    return status;
  }

  // devmgr owns the device now that it's bound
  __UNUSED auto* dummy = device.release();

  return ZX_OK;
}

}  // namespace mbr

namespace {

zx_status_t CreateAndBind(void* ctx, zx_device_t* parent) {
  fbl::Vector<std::unique_ptr<mbr::MbrDevice>> devices;
  fbl::AllocChecker ac;
  devices.reserve(mbr::kMbrNumPartitions, &ac);
  if (!ac.check()) {
    zxlogf(ERROR, "mbr: Failed to allocate devices container");
    return ZX_ERR_NO_MEMORY;
  }
  zx_status_t status;
  if ((status = mbr::MbrDevice::Create(parent, &devices)) != ZX_OK) {
    return status;
  }
  for (auto& device : devices) {
    if (device != nullptr) {
      if ((status = mbr::MbrDevice::Bind(std::move(device))) != ZX_OK) {
        return status;
      }
    }
  }
  return ZX_OK;
}

}  // namespace

zx_driver_ops_t MbrDriverOps = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = CreateAndBind;
  return ops;
}();

ZIRCON_DRIVER(mbr, MbrDriverOps, "zircon", "0.1");
