// Copyright 2018 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 "nand_driver.h"

#include <memory>
#include <new>

#include <ddk/debug.h>
#include <ddktl/protocol/badblock.h>
#include <fbl/array.h>
#include <zircon/assert.h>

#include "nand_operation.h"
#include "oob_doubler.h"

namespace ftl {
extern thread_local int g_nand_op_count;
}

namespace {

void CountNestedOperation() {
  ftl::g_nand_op_count++;
}

uint32_t GetParameter(const char* key) {
  const char* value = getenv(key);
  if (!value) {
    return 0;
  }
  return static_cast<uint32_t>(strtoul(value, nullptr, 0));
}

class NandDriverImpl final : public ftl::NandDriver {
 public:
  NandDriverImpl(const nand_protocol_t* parent, const bad_block_protocol_t* bad_block)
      : parent_(parent), bad_block_protocol_(bad_block) {}
  ~NandDriverImpl() final {}

  // NdmDriver interface:
  const char* Init() final;
  const char* Attach(const ftl::Volume* ftl_volume) final;
  bool Detach() final;
  int NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer, void* oob_buffer) final;
  int NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
                const void* oob_buffer) final;
  int NandErase(uint32_t page_num) final;
  int IsBadBlock(uint32_t page_num) final;
  bool IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) final;

  const fuchsia_hardware_nand_Info& info() const final { return info_; }

 private:
  // Returns true if initialization was performed with an alternate configuration.
  // |options| is passed by value, so a temporary object will be created by the
  // compiler.
  bool HandleAlternateConfig(const ftl::Volume* ftl_volume, ftl::VolumeOptions options);
  bool GetBadBlocks();

  ftl::OobDoubler parent_;
  size_t op_size_ = 0;
  fuchsia_hardware_nand_Info info_ = {};
  const bad_block_protocol_t* bad_block_protocol_;
  fbl::Array<uint32_t> bad_blocks_;
};

const char* NandDriverImpl::Init() {
  parent_.Query(&info_, &op_size_);
  zxlogf(INFO, "FTL: Nand: page_size %u, block size %u, %u blocks, %u ecc, %u oob, op size %lu\n",
         info_.page_size, info_.pages_per_block, info_.num_blocks, info_.ecc_bits, info_.oob_size,
         op_size_);

  if (!GetBadBlocks()) {
    return "Failed to query bad blocks";
  }

  ZX_DEBUG_ASSERT(info_.oob_size >= 16);
  return nullptr;
}

const char* NandDriverImpl::Attach(const ftl::Volume* ftl_volume) {
  ftl::VolumeOptions options = {
      .num_blocks = info_.num_blocks,
      // This should be 2%, but that is of the whole device, not just this partition.
      // TODO(39372): This value should be provided by the stack. For now, use 2% for
      // small disks (likely tests).
      .max_bad_blocks = info_.num_blocks > 1000 ? 41 : info_.num_blocks / 50,
      .block_size = info_.page_size * info_.pages_per_block,
      .page_size = info_.page_size,
      .eb_size = info_.oob_size,
      // If flags change, make sure that HandleAlternateConfig() still makes sense.
      .flags = ftl::kReadOnlyInit};

  if (!IsNdmDataPresent(options)) {
    if (HandleAlternateConfig(ftl_volume, options)) {
      // Already handled.
      return nullptr;
    }
    options.flags = 0;
  } else if (BadBbtReservation()) {
    return "Unable to use bad block reservation";
  }

  const char* error = CreateNdmVolume(ftl_volume, options);
  if (error) {
    // Retry allowing the volume to be fixed as needed.
    zxlogf(INFO, "FTL: About to retry volume creation\n");
    options.flags = 0;
    error = CreateNdmVolume(ftl_volume, options);
  }
  return error;
}

bool NandDriverImpl::Detach() { return RemoveNdmVolume(); }

// Returns kNdmOk, kNdmUncorrectableEcc, kNdmFatalError or kNdmUnsafeEcc.
int NandDriverImpl::NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer,
                             void* oob_buffer) {
  CountNestedOperation();
  ftl::NandOperation operation(op_size_);
  uint32_t data_pages = page_buffer ? page_count : 0;
  size_t data_size = data_pages * info_.page_size;
  size_t oob_size = (oob_buffer ? page_count : 0) * info_.oob_size;
  size_t num_bytes = data_size + oob_size;

  nand_operation_t* op = operation.GetOperation();
  op->rw.command = NAND_OP_READ;
  op->rw.offset_nand = start_page;
  op->rw.length = page_count;

  zx_status_t status = ZX_OK;
  if (page_buffer) {
    status = operation.SetDataVmo(num_bytes);
    if (status != ZX_OK) {
      zxlogf(ERROR, "FTL: SetDataVmo Failed: %d\n", status);
      return ftl::kNdmFatalError;
    }
  }

  if (oob_buffer) {
    status = operation.SetOobVmo(num_bytes);
    op->rw.offset_oob_vmo = data_pages;
    if (status != ZX_OK) {
      zxlogf(ERROR, "FTL: SetOobVmo Failed: %d\n", status);
      return ftl::kNdmFatalError;
    }
  }

  zxlogf(SPEW, "FTL: Read page, start %d, len %d\n", start_page, page_count);
  status = operation.Execute(&parent_);
  if (status == ZX_ERR_IO_DATA_INTEGRITY) {
    return ftl::kNdmUncorrectableEcc;
  }

  if (status != ZX_OK) {
    zxlogf(ERROR, "FTL: Read failed: %d\n", status);
    return ftl::kNdmFatalError;
  }

  if (page_buffer) {
    memcpy(page_buffer, operation.buffer(), data_size);
  }

  if (oob_buffer) {
    memcpy(oob_buffer, operation.buffer() + data_size, oob_size);
  }

  // This threshold is somewhat arbitrary, and should be adjusted if we deal
  // with multiple controllers (by making it part of the nand protocol), or
  // if we find it inappropriate after running endurance tests. We could also
  // decide we need the FTL to have a more active role detecting blocks that
  // should be moved around.
  if (op->rw.corrected_bit_flips > info_.ecc_bits / 2) {
    return ftl::kNdmUnsafeEcc;
  }

  return ftl::kNdmOk;
}

// Returns kNdmOk, kNdmError or kNdmFatalError. kNdmError triggers marking the block as bad.
int NandDriverImpl::NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
                              const void* oob_buffer) {
  CountNestedOperation();
  ftl::NandOperation operation(op_size_);
  uint32_t data_pages = page_buffer ? page_count : 0;
  size_t data_size = data_pages * info_.page_size;
  size_t oob_size = (oob_buffer ? page_count : 0) * info_.oob_size;
  size_t num_bytes = data_size + oob_size;

  nand_operation_t* op = operation.GetOperation();
  op->rw.command = NAND_OP_WRITE;
  op->rw.offset_nand = start_page;
  op->rw.length = page_count;

  zx_status_t status = ZX_OK;
  if (page_buffer) {
    status = operation.SetDataVmo(num_bytes);
    if (status != ZX_OK) {
      zxlogf(ERROR, "FTL: SetDataVmo Failed: %d\n", status);
      return ftl::kNdmFatalError;
    }
    memcpy(operation.buffer(), page_buffer, data_size);
  }

  if (oob_buffer) {
    status = operation.SetOobVmo(num_bytes);
    op->rw.offset_oob_vmo = data_pages;
    if (status != ZX_OK) {
      zxlogf(ERROR, "FTL: SetOobVmo Failed: %d\n", status);
      return ftl::kNdmFatalError;
    }
    memcpy(operation.buffer() + data_size, oob_buffer, oob_size);
  }

  zxlogf(SPEW, "FTL: Write page, start %d, len %d\n", start_page, page_count);
  status = operation.Execute(&parent_);
  if (status != ZX_OK) {
    return status == ZX_ERR_IO ? ftl::kNdmError : ftl::kNdmFatalError;
  }

  return ftl::kNdmOk;
}

// Returns kNdmOk or kNdmError. kNdmError triggers marking the block as bad.
int NandDriverImpl::NandErase(uint32_t page_num) {
  CountNestedOperation();
  uint32_t block_num = page_num / info_.pages_per_block;
  ftl::NandOperation operation(op_size_);

  nand_operation_t* op = operation.GetOperation();
  op->erase.command = NAND_OP_ERASE;
  op->erase.first_block = block_num;
  op->erase.num_blocks = 1;

  zxlogf(SPEW, "FTL: Erase block num %d\n", block_num);

  zx_status_t status = operation.Execute(&parent_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FTL: NandErase failed: %d\n", status);
    return status == ZX_ERR_IO ? ftl::kNdmError : ftl::kNdmFatalError;
  }

  return ftl::kNdmOk;
}

// Returns kTrue, kFalse or kNdmError.
int NandDriverImpl::IsBadBlock(uint32_t page_num) {
  if (!bad_blocks_.size()) {
    return ftl::kFalse;
  }

  // The list should be really short.
  uint32_t block_num = page_num / info_.pages_per_block;
  for (uint32_t bad_block : bad_blocks_) {
    if (bad_block == block_num) {
      zxlogf(ERROR, "FTL: IsBadBlock(%d) found\n", block_num);
      return ftl::kTrue;
    }
  }
  return ftl::kFalse;
}

bool NandDriverImpl::IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) {
  return IsEmptyPageImpl(data, info_.page_size, spare, info_.oob_size);
}

bool NandDriverImpl::HandleAlternateConfig(const ftl::Volume* ftl_volume,
                                           ftl::VolumeOptions options) {
  uint32_t num_blocks = GetParameter("driver.ftl.original-size");
  if (!num_blocks || num_blocks >= info_.num_blocks) {
    return false;
  }
  options.num_blocks = num_blocks;

  if (!IsNdmDataPresent(options)) {
    // Nothing at the alternate location.
    return false;
  }
  RemoveNdmVolume();

  options.flags = 0;  // Allow automatic fixing of errors.
  zxlogf(INFO, "FTL: About to read volume of size %u blocks\n", num_blocks);
  if (!IsNdmDataPresent(options)) {
    zxlogf(ERROR, "FTL: Failed to read initial volume\n");
    return true;
  }

  if (!SaveBadBlockData()) {
    zxlogf(ERROR, "FTL: Failed to extract bad block table\n");
    return true;
  }
  RemoveNdmVolume();

  options.num_blocks = info_.num_blocks;
  if (!IsNdmDataPresent(options)) {
    zxlogf(ERROR, "FTL: Failed to NDM extend volume\n");
    return true;
  }
  if (!RestoreBadBlockData()) {
    zxlogf(ERROR, "FTL: Failed to write bad block table\n");
    return true;
  }

  const char* error = CreateNdmVolume(ftl_volume, options);
  if (error) {
    zxlogf(ERROR, "FTL: Failed to extend volume: %s\n", error);
  } else {
    zxlogf(INFO, "FTL: Volume successfully extended\n");
  }

  return true;
}

bool NandDriverImpl::GetBadBlocks() {
  if (!bad_block_protocol_->ops) {
    return true;
  }
  ddk::BadBlockProtocolClient client(const_cast<bad_block_protocol_t*>(bad_block_protocol_));

  size_t num_bad_blocks;
  zx_status_t status = client.GetBadBlockList(nullptr, 0, &num_bad_blocks);
  if (status != ZX_OK) {
    return false;
  }
  if (!num_bad_blocks) {
    return true;
  }

  std::unique_ptr<uint32_t[]> bad_block_list(new uint32_t[num_bad_blocks]);
  size_t new_count;
  status = client.GetBadBlockList(bad_block_list.get(), num_bad_blocks, &new_count);
  if (status != ZX_OK) {
    return false;
  }
  ZX_ASSERT(new_count == num_bad_blocks);

  bad_blocks_ = fbl::Array<uint32_t>(bad_block_list.release(), num_bad_blocks);

  for (uint32_t bad_block : bad_blocks_) {
    zxlogf(ERROR, "FTL: Bad block: %x\n", bad_block);
  }
  return true;
}

}  // namespace

namespace ftl {

// Static.
std::unique_ptr<NandDriver> NandDriver::Create(const nand_protocol_t* parent,
                                               const bad_block_protocol_t* bad_block) {
  return std::unique_ptr<NandDriver>(new NandDriverImpl(parent, bad_block));
}

}  // namespace ftl.
