// 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 <fidl/fuchsia.hardware.block/cpp/wire.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <stdarg.h>
#include <stdlib.h>

#include <utility>

#include <fbl/array.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(fidl::UnownedClientEnd<fuchsia_hardware_block::Block> block, uint32_t block_size,
          bool silent);
  Checker(fidl::UnownedClientEnd<fuchsia_io::File> file, uint32_t block_size, bool silent);

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

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

    // Prints the format string and arguments to stderr.
    static void Error(const char* format, ...) {
      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:
    const bool silent_;
  };

  class Interface {
   public:
    virtual ~Interface() = default;

    virtual zx::result<size_t> Size() const = 0;
    virtual zx::result<size_t> Read(void* buf, size_t count) const = 0;
  };

  Checker(std::unique_ptr<Interface> interface, uint32_t block_size, bool silent);

  class Block : public Interface {
   public:
    explicit Block(fidl::UnownedClientEnd<fuchsia_hardware_block::Block> block);
    ~Block() override;

   private:
    zx::result<size_t> Size() const override;
    zx::result<size_t> Read(void* buf, size_t count) const override;

    const fidl::UnownedClientEnd<fuchsia_hardware_block::Block> block_;
  };

  class File : public Interface {
   public:
    explicit File(fidl::UnownedClientEnd<fuchsia_io::File> file);
    ~File() override;

   private:
    zx::result<size_t> Size() const override;
    zx::result<size_t> Read(void* buf, size_t count) const override;

    const fidl::UnownedClientEnd<fuchsia_io::File> file_;
  };

  // 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(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;

  const std::unique_ptr<Interface> interface_;
  const uint32_t block_size_;
  const Logger logger_;
};

}  // namespace fvm

#endif  // SRC_STORAGE_FVM_FVM_CHECK_H_
