// 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 <lib/ftl/ndm-driver.h>
#include <stdarg.h>
#include <zircon/assert.h>

#include <memory>
#include <optional>

#include "ftl.h"
#include "ftl_private.h"
#include "ftlnp.h"
#include "ndm/ndmp.h"

namespace ftl {

namespace {

// Many of the NDM driver functions and tests require that these constants match. If they ever
// are updated to be unique constants, the various API contacts need to be updated accordingly.
static_assert(kNdmUncorrectableEcc == kNdmError, "kNdmUncorrectableEcc should map to kNdmError!");

bool g_init_performed = false;

// Extra configuration data saved to the partition info.
struct UserData {
  uint16_t major_version = 1;
  uint16_t minor_version = 0;
  uint32_t ftl_flags;   // Flags used to create the FtlNdmVol structure.
  uint32_t extra_free;  // Overallocation for the FTL.
  uint32_t reserved_1[5];
  VolumeOptions options;
  uint32_t reserved_2[10];
};
static_assert(sizeof(UserData) == 96);

// This structure exposes the two views into the partition data.
// See ftl.h for the definition of NDMPartitionInfo.
union PartitionInfo {
  NDMPartitionInfo ndm;
  struct {
    // This is the equivalent structure, with an explicit |data| field of the
    // "correct" type, instead of just a placeholder. In this case, |data_size|
    // tracks |data|.
    NDMPartition basic_data;
    uint32_t data_size = sizeof(UserData);
    UserData data;
  } exploded;
};
static_assert(sizeof(NDMPartition) + sizeof(uint32_t) == sizeof(NDMPartitionInfo));
static_assert(sizeof(NDMPartitionInfo) + sizeof(UserData) == sizeof(PartitionInfo));

// Fills |data| with the desired configuration info.
void CopyConfigData(const VolumeOptions& options, const FtlNdmVol& ftl, UserData* data) {
  data->ftl_flags = ftl.flags;
  data->extra_free = ftl.extra_free;
  data->options = options;
}

// Implementation of the driver interface:

// Returns kNdmOk, kNdmUncorrectableEcc, kNdmFatalError or kNdmUnsafeEcc.
int ReadPagesImpl(uint32_t page, uint32_t count, uint8_t* data, uint8_t* spare, void* dev) {
  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  return device->NandRead(page, count, data, spare);
}

// Returns kNdmOk, kNdmUncorrectableEcc, kNdmFatalError or kNdmUnsafeEcc.
int ReadPages(uint32_t page, uint32_t count, uint8_t* data, uint8_t* spare, void* dev) {
  return ReadPagesImpl(page, count, data, nullptr, dev);
}

// Returns kNdmOk, kNdmUncorrectableEcc, kNdmFatalError or kNdmUnsafeEcc.
int ReadPage(uint32_t page, uint8_t* data, uint8_t* spare, void* dev) {
  return ReadPagesImpl(page, 1, data, nullptr, dev);
}

// Returns kNdmOk, kNdmFatalError, or kNdmUncorrectableEcc on ECC decode failure.
int ReadSpare(uint32_t page, uint8_t* spare, void* dev) {
  int result = ReadPagesImpl(page, 1, nullptr, spare, dev);
  // Ensure we translate errors to the correct values above, since
  // kNdmUnsafeEcc is OK as the data is still correct.
  return result == kNdmUnsafeEcc ? kNdmOk : result;
}

// Returns kNdmOk, kNdmError or kNdmFatalError. kNdmError triggers marking the block as bad.
int WritePages(uint32_t page, uint32_t count, const uint8_t* data, uint8_t* spare, int action,
               void* dev) {
  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  for (uint32_t i = 0; i < count; i++) {
    FtlnSetSpareValidity(&spare[i * device->SpareSize()], &data[i * device->PageSize()],
                         device->PageSize());
  }
  return device->NandWrite(page, count, data, spare);
}

// Returns kNdmOk, kNdmError or kNdmFatalError. kNdmError triggers marking the block as bad.
int WritePage(uint32_t page, const uint8_t* data, uint8_t* spare, int action, void* dev) {
  return WritePages(page, 1, data, spare, action, dev);
}

// Returns kNdmOk or kNdmError. kNdmError triggers marking the block as bad.
int EraseBlock(uint32_t page, void* dev) {
  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  return device->NandErase(page);
}

// Returns kTrue, kFalse or kNdmError.
int IsBadBlockImpl(uint32_t page, void* dev) {
  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  return device->IsBadBlock(page);
}

// Returns kTrue or kFalse (kFalse on error).
int IsEmpty(uint32_t page, uint8_t* data, uint8_t* spare, void* dev) {
  int result = ReadPagesImpl(page, 1, data, spare, dev);

  // kNdmUncorrectableEcc and kNdmUnsafeEcc are ok.
  if (result == kNdmFatalError) {
    return kFalse;
  }

  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  return device->IsEmptyPage(page, data, spare) ? kTrue : kFalse;
}

// Returns kNdmOk or kNdmFatalError, where kNdmFatalError implies aborting initialization.
int CheckPage(uint32_t page, uint8_t* data, uint8_t* spare, int* status, void* dev) {
  int result = ReadPagesImpl(page, 1, data, spare, dev);

  if (result == kNdmFatalError) {
    *status = NDM_PAGE_INVALID;
    return kNdmFatalError;
  }

  // Mark page as invalid if the data fails ECC or if we detected a partial page write, since both
  // the page and spare data should not be used in that case.
  NdmDriver* device = reinterpret_cast<NdmDriver*>(dev);
  if (result == kNdmUncorrectableEcc || device->IncompletePageWrite(spare, data)) {
    *status = NDM_PAGE_INVALID;
    return kNdmOk;
  }

  *status = device->IsEmptyPage(page, data, spare) ? NDM_PAGE_ERASED : NDM_PAGE_VALID;
  return kNdmOk;
}

__PRINTFLIKE(3, 4) void LogTrace(const char* file, int line, const char* format, ...) {
  fprintf(stderr, "[FTL] TRACE: ");
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fprintf(stderr, "\n");
}

__PRINTFLIKE(3, 4) void LogDebug(const char* file, int line, const char* format, ...) {
  fprintf(stderr, "[FTL] DEBUG: ");
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fprintf(stderr, "\n");
}

__PRINTFLIKE(3, 4) void LogInfo(const char* file, int line, const char* format, ...) {
  fprintf(stderr, "[FTL] INFO: ");
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fprintf(stderr, "\n");
}

__PRINTFLIKE(3, 4) void LogWarning(const char* file, int line, const char* format, ...) {
  fprintf(stderr, "[FTL] WARNING: ");
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fprintf(stderr, "\n");
}

__PRINTFLIKE(3, 4) void LogError(const char* file, int line, const char* format, ...) {
  fprintf(stderr, "[FTL] ERROR: ");
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fprintf(stderr, "\n");
}

}  // namespace

FtlLogger DefaultLogger() {
  return FtlLogger{
      .trace = &LogTrace,
      .debug = &LogDebug,
      .info = &LogInfo,
      .warn = &LogWarning,
      .error = &LogError,
  };
}

NdmBaseDriver::~NdmBaseDriver() { RemoveNdmVolume(); }

bool NdmBaseDriver::IsNdmDataPresent(const VolumeOptions& options, bool use_format_v2) {
  NDMDrvr driver;
  FillNdmDriver(options, use_format_v2, &driver);

  SetFsErrCode(NDM_OK);
  ndm_ = ndmAddDev(&driver);
  return ndm_ || GetFsErrCode() != NDM_NO_META_BLK;
}

bool NdmBaseDriver::BadBbtReservation() const {
  if (ndm_) {
    return false;
  }
  FsErrorCode error = static_cast<FsErrorCode>(GetFsErrCode());
  switch (error) {
    case NDM_TOO_MANY_IBAD:
    case NDM_TOO_MANY_RBAD:
    case NDM_RBAD_LOCATION:
      return true;
    default:
      return false;
  }
}

const char* NdmBaseDriver::CreateNdmVolume(const Volume* ftl_volume, const VolumeOptions& options,
                                           bool save_volume_data) {
  if (!ndm_) {
    IsNdmDataPresent(options, save_volume_data);
  }

  if (!ndm_) {
    return "ndmAddDev failed";
  }

  PartitionInfo partition = {};
  partition.exploded = {};  // Initialize the "real" structure.
  FtlNdmVol ftl = {};
  XfsVol xfs = {};

  ftl.flags = FSF_EXTRA_FREE;
  ftl.cached_map_pages = options.num_blocks * (options.block_size / options.page_size);
  ftl.extra_free = 6;  // Over-provision 6% of the device.
  xfs.ftl_volume = const_cast<Volume*>(ftl_volume);
  ftl.logger = logger_;

  partition.exploded.basic_data.num_blocks = ndmGetNumVBlocks(ndm_);
  strncpy(partition.exploded.basic_data.name, "ftl", sizeof(partition.exploded.basic_data.name));
  CopyConfigData(options, ftl, &partition.exploded.data);

  if (save_volume_data) {
    const NDMPartitionInfo* info = ndmGetPartitionInfo(ndm_);
    if (info) {
      volume_data_saved_ = true;
    }

    if (ndmWritePartitionInfo(ndm_, &partition.ndm) != 0) {
      return "ndmWritePartitionInfo failed";
    }

    if (!info && !(options.flags & kReadOnlyInit)) {
      // There was no volume information saved, save it now.
      if (ndmSavePartitionTable(ndm_) != 0) {
        return "ndmSavePartitionTable failed";
      }
      volume_data_saved_ = true;
    }
  } else {
    // This call also allocates the partition data, but old style.
    if (ndmSetNumPartitions(ndm_, 1) != 0) {
      return "ndmSetNumPartitions failed";
    }

    if (ndmWritePartition(ndm_, &partition.ndm.basic_data, 0, "ftl") != 0) {
      return "ndmWritePartition failed";
    }
  }

  if (ndmAddVolFTL(ndm_, 0, &ftl, &xfs) == NULL) {
    return "ndmAddVolFTL failed";
  }

  return nullptr;
}

bool NdmBaseDriver::RemoveNdmVolume() {
  if (ndm_ && ndmDelDev(ndm_) == 0) {
    ndm_ = nullptr;
    return true;
  }
  return false;
}

bool NdmBaseDriver::SaveBadBlockData() { return ndmExtractBBL(ndm_) >= 0 ? true : false; }

bool NdmBaseDriver::RestoreBadBlockData() { return ndmInsertBBL(ndm_) == 0 ? true : false; }

bool NdmBaseDriver::IsEmptyPageImpl(const uint8_t* data, uint32_t data_len, const uint8_t* spare,
                                    uint32_t spare_len) const {
  const int64_t* pointer = reinterpret_cast<const int64_t*>(data);
  ZX_DEBUG_ASSERT(data_len % sizeof(*pointer) == 0);
  for (size_t i = 0; i < data_len / sizeof(*pointer); i++) {
    if (pointer[i] != -1) {
      return false;
    }
  }

  ZX_DEBUG_ASSERT(spare_len % sizeof(*pointer) == 0);
  pointer = reinterpret_cast<const int64_t*>(spare);
  for (size_t i = 0; i < spare_len / sizeof(*pointer); i++) {
    if (pointer[i] != -1) {
      return false;
    }
  }
  return true;
}

const VolumeOptions* NdmBaseDriver::GetSavedOptions() const {
  const NDMPartitionInfo* partition = ndmGetPartitionInfo(ndm_);
  if (!partition) {
    return nullptr;
  }

  auto info = reinterpret_cast<const PartitionInfo*>(partition);
  if (info->exploded.data_size != sizeof(UserData)) {
    return nullptr;
  }

  if (info->exploded.data.major_version != 1) {
    return nullptr;
  }

  return &info->exploded.data.options;
}

bool NdmBaseDriver::WriteVolumeData() {
  if (ndmSavePartitionTable(ndm_) != 0) {
    return false;
  }
  volume_data_saved_ = true;
  return true;
}

void NdmBaseDriver::FillNdmDriver(const VolumeOptions& options, bool use_format_v2,
                                  NDMDrvr* driver) const {
  *driver = {};
  driver->num_blocks = options.num_blocks;
  driver->max_bad_blocks = options.max_bad_blocks;
  driver->block_size = options.block_size;
  driver->page_size = options.page_size;
  driver->eb_size = options.eb_size;
  driver->flags = FSF_MULTI_ACCESS | FSF_FREE_SPARE_ECC | options.flags;
  driver->format_version_2 = use_format_v2;
  driver->dev = const_cast<NdmBaseDriver*>(this);
  driver->type = NDM_SLC;
  driver->read_pages = ReadPages;
  driver->write_pages = WritePages;
  driver->write_data_and_spare = WritePage;
  driver->read_decode_data = ReadPage;
  driver->read_decode_spare = ReadSpare;
  // Since we have "free" decoding, we use the same ReadSpare function for this callback (which
  // should never be invoked anyways if FSF_FREE_SPARE_ECC is set). If this changes in the future,
  // this callback should be updated and the the FSF_FREE_SPARE_ECC flag cleared.
  driver->read_spare = ReadSpare;
  driver->data_and_spare_erased = IsEmpty;
  driver->data_and_spare_check = CheckPage;
  driver->erase_block = EraseBlock;
  driver->is_block_bad = IsBadBlockImpl;
  driver->logger = logger_;
}

uint32_t NdmBaseDriver::PageSize() { return ndm_->page_size; }

uint8_t NdmBaseDriver::SpareSize() { return ndm_->eb_size; }

bool NdmBaseDriver::IncompletePageWrite(uint8_t* spare, uint8_t* data) {
  return FtlnIncompleteWrite(spare, data, PageSize());
}

__EXPORT
bool InitModules() {
  if (!g_init_performed) {
    // Unfortunately, module initialization is a global affair, and there is
    // no cleanup. At least, make sure no re-initialization takes place.
    if (NdmInit() != 0 || FtlInit() != 0) {
      return false;
    }
    g_init_performed = true;
  }
  return true;
}

}  // namespace ftl
