// 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.

#ifndef LIB_FTL_NDM_DRIVER_H_
#define LIB_FTL_NDM_DRIVER_H_

#include <lib/ftl/logger.h>
#include <zircon/compiler.h>

#include <cstdint>
#include <optional>

struct ndm;
struct NDMDrvr;

namespace ftl {

class Volume;

// Return values expected by NDM from the nand driver.
// See ndm-man-20150.pdf for the complete low level API specification:
constexpr int kNdmOk = 0;
constexpr int kNdmError = -1;
constexpr int kNdmUncorrectableEcc = -1;
constexpr int kNdmFatalError = -2;
constexpr int kNdmUnsafeEcc = 1;
constexpr int kTrue = 1;
constexpr int kFalse = 0;

// Initialization should not alter the contents of the volume.
constexpr uint32_t kReadOnlyInit = (1 << 8);  // Matches FSF_READ_ONLY_INIT.

// Options for a device to be created. All sizes are in bytes.
struct VolumeOptions {
  uint32_t num_blocks;
  uint32_t max_bad_blocks;
  uint32_t block_size;
  uint32_t page_size;
  uint32_t eb_size;  // Extra bytes, a.k.a. OOB.
  uint32_t flags;
};

FtlLogger DefaultLogger();

// Encapsulates the lower layer TargetFtl-Ndm driver.
class __EXPORT NdmDriver {
 public:
  virtual ~NdmDriver() {}

  // Performs driver initialization. Returns an error string, or nullptr on
  // success.
  virtual const char* Init() = 0;

  // Creates a new volume. Note that multiple volumes are not supported.
  // |ftl_volume| (if provided) will be notified with the volume details.
  // Returns an error string, or nullptr on success.
  virtual const char* Attach(const Volume* ftl_volume) = 0;

  // Destroy the volume created with Attach(). Returns true on success.
  virtual bool Detach() = 0;

  // Reads |page_count| pages starting at |start_page|, placing the results on
  // |page_buffer| and |oob_buffer|. Either pointer can be nullptr if that
  // part is not desired.
  // Returns kNdmOk, kNdmUncorrectableEcc, kNdmFatalError or kNdmUnsafeEcc.
  virtual int NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer,
                       void* oob_buffer) = 0;

  // Writes |page_count| pages starting at |start_page|, using the data from
  // |page_buffer| and |oob_buffer|.
  // Returns kNdmOk, kNdmError or kNdmFatalError. kNdmError triggers marking
  // the block as bad.
  virtual int NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
                        const void* oob_buffer) = 0;

  // Erases the block containing |page_num|.
  // Returns kNdmOk or kNdmError. kNdmError triggers marking the block as bad.
  virtual int NandErase(uint32_t page_num) = 0;

  // Returns whether the block containing |page_num| was factory-marked as bad.
  // Returns kTrue, kFalse or kNdmError.
  virtual int IsBadBlock(uint32_t page_num) = 0;

  // Returns whether a given page is empty or not. |data| and |spare| store
  // the contents of the page.
  virtual bool IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) = 0;

  // Returns the number of bytes in a page.
  virtual uint32_t PageSize() = 0;

  // Returns the number of bytes available for spare data storage.
  virtual uint8_t SpareSize() = 0;

  // Looks at the spare  and data buffer to try to determine if the write may
  // have been incomplete. Return true if it appears to have been incomplete.
  virtual bool IncompletePageWrite(uint8_t* spare, uint8_t* data) = 0;
};

// Base functionality for a driver implementation.
class __EXPORT NdmBaseDriver : public NdmDriver {
 public:
  NdmBaseDriver(FtlLogger logger) : logger_(logger) {}
  virtual ~NdmBaseDriver();

  // Returns true if known data appears to be present on the device. This does
  // not imply that creating a volume will not find errors, just that calling
  // CreateNdmVolume after this method returns false will result in a freshly
  // minted (aka empty) volume.
  // This method should be called after Init(), but before CreateNdmVolume(),
  // for the result to be meaningful, but calling this is not required.
  // |use_format_v2| tells NDM to use the latest file format for the volume, if
  // a new volume is eventually created.
  bool IsNdmDataPresent(const VolumeOptions& options, bool use_format_v2 = true);

  // Returns true if the size of the bad block reservation cannot be used.
  // The size to use (options.max_bad_blocks) may be too small to hold the
  // current known bad blocks, or some internal value may be inconsistent if
  // this size is used.
  // This only makes sense when comparing the desired options with the data
  // already stored on a volume, and in general should only be used to attempt
  // to reduce the reserved space (increasing it would reduce the size of the
  // visible volume, and that is not supported).
  // This method should only be called right after calling IsNdmDataPresent(),
  // before calling CreateNdmVolume().
  bool BadBbtReservation() const;

  // Creates the underlying NDM volume, with the provided parameters. Setting
  // |save_volume_data| to true enables writing of NDM control data version 2.
  const char* CreateNdmVolume(const Volume* ftl_volume, const VolumeOptions& options,
                              bool save_volume_data = true);

  // Deletes the underlying NDM volume.
  bool RemoveNdmVolume();

  // Saves and restores bad block data for volume extension.
  bool SaveBadBlockData();
  bool RestoreBadBlockData();

  // Inspects |data_len| bytes from |data| and |spare_len| bytes from |spare|
  // looking for a typical empty (erased) page. Returns true if all bits are 1.
  bool IsEmptyPageImpl(const uint8_t* data, uint32_t data_len, const uint8_t* spare,
                       uint32_t spare_len) const;

  // Returns the settings used for the volume. The NDM volume has to be created
  // with |save_volume_data| set to true.
  const VolumeOptions* GetSavedOptions() const;

  // Returns true when volume data is saved on disk, either from a previous run
  // or written by this run.
  bool volume_data_saved() const { return volume_data_saved_; }

  // Writes volume information to storage. Returns true on success.
  // This should only be called after a successful call to CreateNdmVolume with
  // save_volume_data set to true.
  bool WriteVolumeData();

  bool IncompletePageWrite(uint8_t* spare, uint8_t* data) override;

  uint32_t PageSize() override;
  uint8_t SpareSize() override;

 protected:
  // This is exposed for unit tests only.
  ndm* GetNdmForTest() const { return ndm_; }

  // This is exposed for unit tests only.
  void FillNdmDriver(const VolumeOptions& options, bool use_format_v2, NDMDrvr* driver) const;

 private:
  ndm* ndm_ = nullptr;
  bool volume_data_saved_ = false;
  const FtlLogger logger_;
};

// Performs global module initialization. This is exposed to support unit tests,
// and while calling this function multiple times is supported, racing calls are
// not (or more generally, calling this from multiple threads).
// If multiple simultaneous tests from the same test instance ever becomes a
// thing, this should be called from testing::Environment and not from each
// test case.
bool InitModules();

}  // namespace ftl

#endif  // LIB_FTL_NDM_DRIVER_H_
