// 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 SRC_STORAGE_FVM_FVM_CHECK_H_
#define SRC_STORAGE_FVM_FVM_CHECK_H_

#include <stdarg.h>
#include <stdlib.h>

#include <utility>

#include <fbl/array.h>
#include <fbl/unique_fd.h>
#include <fbl/vector.h>

#include "src/storage/fvm/format.h"

namespace fvm {

// Checker defines a class which may be used to validate an FVM
// (provided as either a regular file or a raw block device).
class Checker {
 public:
  Checker();
  Checker(fbl::unique_fd fd, uint32_t block_size, bool silent);
  ~Checker();

  // Sets the path of the block device / image to read the FVM from.
  void SetDevice(fbl::unique_fd fd) { fd_ = std::move(fd); }

  // Sets the block size of the provided device. Not automatically queried from the underlying
  // device, since this checker may operate on a regular file, which does not have an
  // attached block size.
  void SetBlockSize(uint32_t block_size) { block_size_ = block_size; }

  // Toggles the output of future calls to |Log|.
  void SetSilent(bool silent) { logger_.SetSilent(silent); }

  // Read from and validate the provided device, logging information if requested.
  bool Validate() const;

 private:
  class Logger {
   public:
    Logger() : silent_(false) {}
    explicit Logger(bool silent) : silent_(silent) {}

    // Toggles the output of future calls to |Log|.
    void SetSilent(bool silent) { silent_ = silent; }

    // Prints the format string and arguments to stderr.
    void Error(const char* format, ...) const {
      va_list arg;
      va_start(arg, format);
      vprintf(format, arg);
      va_end(arg);
    }

    // Prints the format string and arguments to stdout, unless explicitly silenced.
    void Log(const char* format, ...) const {
      va_list arg;
      if (!silent_) {
        va_start(arg, format);
        vprintf(format, arg);
        va_end(arg);
      }
    }

   private:
    bool silent_;
  };

  // Cached information from loading and validating the FVM.
  struct FvmInfo {
    // Contains both copies of metadata.
    fbl::Array<uint8_t> metadata;
    size_t valid_metadata_offset;
    const uint8_t* valid_metadata;
    const uint8_t* invalid_metadata;
    size_t block_size;
    size_t block_count;
    size_t device_size;
    size_t slice_size;
  };

  struct Slice {
    uint64_t virtual_partition;
    uint64_t virtual_slice;
    uint64_t physical_slice;
  };

  struct Partition {
    bool Allocated() const { return entry != nullptr; }

    const fvm::VPartitionEntry* entry = nullptr;
    fbl::Vector<Slice> slices;
  };

  // Parses the FVM info from the device, and validate it (minimally).
  bool LoadFVM(FvmInfo* out) const;

  // Outputs and checks information about the FVM, optionally logging parsed information.
  bool CheckFVM(const FvmInfo& info) const;

  // Acquires a list of slices and partitions while parsing the FVM.
  //
  // Returns false if the FVM contains contradictory or invalid data.
  bool LoadPartitions(const size_t slice_count, const fvm::SliceEntry* slice_table,
                      const fvm::VPartitionEntry* vpart_table, fbl::Vector<Slice>* out_slices,
                      fbl::Array<Partition>* out_partitions) const;

  // Displays information about |slices|, assuming they are sorted in physical slice order.
  void DumpSlices(const fbl::Vector<Slice>& slices) const;

  // Confirms the Checker has received necessary arguments before beginning validation.
  bool ValidateOptions() const;

  fbl::unique_fd fd_;
  uint32_t block_size_ = 512;
  Logger logger_;
};

}  // namespace fvm

#endif  // SRC_STORAGE_FVM_FVM_CHECK_H_
