// Copyright 2017 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_FVM_FORMAT_H__
#define __LIB_FVM_FORMAT_H__

#include <digest/digest.h>
#include <stdlib.h>
#include <string.h>

#ifdef __cplusplus

#include <limits>
#include <type_traits>

#include <fbl/algorithm.h>
#include <gpt/gpt.h>

namespace fvm {

// Unique identifier mapped to a GPT partition that contains a FVM.
static constexpr uint64_t kMagic = 0x54524150204d5646;

// Current version of the FVM format being handled by this library.
static constexpr uint64_t kVersion = 0x00000001;

// Defines the block size of that the FVM driver exposes.
static constexpr uint64_t kBlockSize = 8192;

// Maximum number of virtual partitions that can be created.
static constexpr uint64_t kMaxVPartitions = 1024;

// Maximum size for a partition GUID.
static constexpr uint64_t kGuidSize = GPT_GUID_LEN;

// Maximum string length for virtual partition GUID.
static constexpr uint64_t kGuidStrLen = GPT_GUID_STRLEN;

// Maximum length allowed for a virtual partition name.
static constexpr uint16_t kMaxVPartitionNameLength = 24;

// Number of bits required for the VSlice address space.
static constexpr uint64_t kSliceEntryVSliceBits = 32;

// Number of bits required for the VPartition address space.
static constexpr uint64_t kSliceEntryVPartitionBits = 16;

// Maximum number of VSlices that can be addressed.
static constexpr uint64_t kMaxVSlices = 1ull << (kSliceEntryVSliceBits - 1);

namespace internal {
// Minimal safety checks for persisted data structures. Currently they are required to be trivial
// and standard layout.
template <typename T>
struct is_persistable {
    static constexpr bool value = std::is_standard_layout<T>::value && std::is_trivial<T>::value;
};

// FVM block alignment properties for a given type.
template <typename T>
struct block_alignment {
    static constexpr bool may_cross_boundary = (kBlockSize % sizeof(T)) != 0;
    static constexpr bool ends_at_boundary = (sizeof(T) % kBlockSize);
};
} // namespace internal

// FVM header which describes the contents and layout of the volume manager.
struct Header {
    // Unique identifier for this format type.
    uint64_t magic;
    // Version of the format.
    uint64_t version;
    // Number of slices which can be addressed and allocated by the virtual parititons.
    uint64_t pslice_count;
    // Size of the each slice in size.
    uint64_t slice_size;
    // Size of the volume the fvm described by this header is expecting to interact with.
    uint64_t fvm_partition_size;
    // Size of the partition table of the superblock the header describes, which contains
    // partition metadata.
    uint64_t vpartition_table_size;
    // Size of the allocation table allocated size. This includes extra space allowing the
    // fvm to grow as the underlying volume grows. The actual allocation table size, which defines
    // the number of slices that can be addressed, is determined by |fvm_partition_size|.
    uint64_t allocation_table_size;
    // Use to determine over two copies(primary, secondary) of superblock, which one is the latest
    // one.
    uint64_t generation;
    // Integrity check.
    uint8_t hash[SHA256_DIGEST_LENGTH];
    // Fill remainder of the block.
    uint8_t reserved[0];
};

// TODO(gevalentino): Remove once all callsites have been updated.
using fvm_t = Header;

static_assert(internal::is_persistable<Header>::value && sizeof(Header) <= kBlockSize,
              "fvm::Header must fit within one block, be trivial and match standard layout.");

// Represent an entry in the FVM Partition table, which is fixed size contiguous flat buffer.
struct VPartitionEntry {

    // Returns a new blank entry.
    static VPartitionEntry Create() {
        VPartitionEntry entry;
        entry.Release();
        return entry;
    }

    // Returns a new entry with a the respective |type|, |guid|, |name|, |slices| and |flags|.
    // Note: This is subject to NRVO.
    static VPartitionEntry Create(const uint8_t* type, const uint8_t* guid, uint32_t slices,
                                  const char* name, uint32_t flags);

    // Returns the allowed set of flags in |raw_flags|.
    static uint32_t ParseFlags(uint32_t raw_flags);

    // Returns true if the entry is allocated.
    bool IsAllocated() const;

    // Returns true if the entry is free.
    bool IsFree() const;

    // Releases the partition, marking it as free.
    void Release();

    // Returns true if the partition is should be treated as active..
    bool IsActive() const;

    // Returns true if the partition is flagged as inactive.
    bool IsInactive() const;

    // Marks this entry active status as |is_active|.
    void SetActive(bool is_active);

    // Mirrors GPT value.
    uint8_t type[kGuidSize];

    // Mirrors GPT value.
    uint8_t guid[kGuidSize];

    // Number of allocated slices.
    uint32_t slices;

    uint32_t flags;

    // Partition name.
    uint8_t name[fvm::kMaxVPartitionNameLength];
};

// TODO(gevalentino): remove after updating callsites.
using vpart_entry_t = VPartitionEntry;

static_assert(sizeof(VPartitionEntry) == 64, "Unchecked VPartitionEntry size change.");
static_assert(internal::is_persistable<VPartitionEntry>::value,
              "VPartitionEntry must be standard layout compilant and trivial.");
static_assert(!internal::block_alignment<VPartitionEntry>::may_cross_boundary,
              "VPartitionEntry must not cross block boundary.");
static_assert(!internal::block_alignment<VPartitionEntry[kMaxVPartitions]>::ends_at_boundary,
              "VPartitionEntry table max size must end at block boundary.");

// A Slice Entry represents the allocation of a slice.
//
// Slice Entries are laid out in an array on disk.  The index into this array
// determines the "physical slice" being accessed, where physical slices consist
// of all disk space immediately following the FVM metadata on an FVM partition.
//
struct SliceEntry {
    // Returns a new blank entry.
    static SliceEntry Create() {
        SliceEntry entry;
        entry.Release();
        return entry;
    }

    // Returns a slice entry with vpartition and vslice set.
    static SliceEntry Create(uint64_t vpartition, uint64_t vslice);

    // Returns true if this slice is assigned to a partition.
    bool IsAllocated() const;

    // Returns true if this slice is unassigned.
    bool IsFree() const;

    // Resets the slice entry, marking it as Free.
    void Release();

    // Returns the |vpartition| that owns this slice.
    uint64_t VPartition() const;

    // Returns the |vslice| of this slice. This represents the relative order of the slices
    // assigned to |vpartition|. This is, the block device exposed to |partition| sees an array of
    // all slices assigned to it, sorted by |vslice|.
    uint64_t VSlice() const;

    // Sets the contents of the slice entry to |partition| and |slice|.
    void Set(uint64_t vpartition, uint64_t vslice);

    // Packed entry, the format must remain obscure to the user.
    uint64_t data;
};

using slice_entry_t = SliceEntry;

static_assert(sizeof(SliceEntry) == 8, "Unchecked SliceEntry size change.");
static_assert(internal::is_persistable<SliceEntry>::value,
              "VSliceEntry must meet persistable constraints.");
static_assert(!internal::block_alignment<SliceEntry>::may_cross_boundary,
              "VSliceEntry must not cross block boundary.");

// Partition Table.
// TODO(gevalentino): Upgrade this into a class that provides a view into a an unowned buffer, so
// the logic for calculating offsets and accessing respective entries is hidden.
struct PartitionTable {
    // The Partition table starts at the next block after the respective header.
    static constexpr uint64_t kOffset = kBlockSize;

    // The Partition table size will finish at a block boundary, which is determined by the maximum
    // allowed number of partitions.
    static constexpr uint64_t kLength = sizeof(VPartitionEntry) * kMaxVPartitions;
};

// Allocation Table.
// TODO(gevalentino): Upgrade this into a class that provides a view into a an unowned buffer, so
// the logic for calculating offsets and accessing respective entries is hidden.
struct AllocationTable {
    // The allocation table offset with respect to the start of the header.
    static constexpr uint64_t kOffset = PartitionTable::kOffset + PartitionTable::kLength;

    // Returns an over estimation of size required to allocate all slices in a fvm_volume of
    // |fvm_disk_size| with a given |slice_size|. The returned value is always rounded to the next
    // block boundary.
    constexpr uint64_t Length(size_t fvm_disk_size, size_t slice_size) {
        return fbl::round_up(sizeof(SliceEntry) * (fvm_disk_size / slice_size), kBlockSize);
    }
};

// Remove this.
constexpr size_t kVPartTableOffset = PartitionTable::kOffset;
constexpr size_t kVPartTableLength = PartitionTable::kLength;
constexpr size_t kAllocTableOffset = AllocationTable::kOffset;

constexpr size_t AllocTableLength(size_t total_size, size_t slice_size) {
    return fbl::round_up(sizeof(slice_entry_t) * (total_size / slice_size), fvm::kBlockSize);
}

constexpr size_t MetadataSize(size_t total_size, size_t slice_size) {
    return kAllocTableOffset + AllocTableLength(total_size, slice_size);
}

constexpr size_t BackupStart(size_t total_size, size_t slice_size) {
    return MetadataSize(total_size, slice_size);
}

constexpr size_t SlicesStart(size_t total_size, size_t slice_size) {
    return 2 * MetadataSize(total_size, slice_size);
}

constexpr size_t UsableSlicesCount(size_t total_size, size_t slice_size) {
    return (total_size - SlicesStart(total_size, slice_size)) / slice_size;
}

constexpr size_t BlocksToSlices(size_t slice_size, size_t block_size, size_t block_count) {
    if (slice_size == 0 || slice_size < block_size) {
        return 0;
    }

    const size_t kBlocksPerSlice = slice_size / block_size;
    return (block_count + kBlocksPerSlice - 1) / kBlocksPerSlice;
}

constexpr size_t SlicesToBlocks(size_t slice_size, size_t block_size, size_t slice_count) {
    return slice_count * slice_size / block_size;
}

// Defines the type of superblocks of an FVM. The key difference is how the offset from the
// beginning is calculated. They both share the same format.
enum class SuperblockType {
    kPrimary,
    kSecondary,
};

// Helper class for obtaining information about the format of a FVM, such as superblock offsets,
// metadata size, allocated sizes, etc.
//
// This class is copyable and moveable.
class FormatInfo {
public:
    // Returns a FormatInfo from a Fvm header and a disk size.
    static FormatInfo FromSuperBlock(const fvm_t& superblock);

    // Assumes a superblock created from the given disk for the given disk size,
    // with slice size. (No Preallocated metadata headers for future growth).
    static FormatInfo FromDiskSize(size_t disk_size, size_t slice_size);

    // Without instantiating a SuperBlock, assumes that an fvm will be formatted initially with
    // |initial_size| and eventually will grow up to |max_size| with |slice_size|.
    static FormatInfo FromPreallocatedSize(size_t initial_size, size_t max_size, size_t slice_size);

    FormatInfo() = default;
    FormatInfo(const FormatInfo&) = default;
    FormatInfo(FormatInfo&&) = default;
    FormatInfo& operator=(const FormatInfo&) = default;
    FormatInfo& operator=(FormatInfo&&) = default;
    ~FormatInfo() = default;

    // Returns the size of the addressable metadata in a FVM header.
    size_t metadata_size() const { return metadata_size_; }

    // Returns the size of the allocated metadata SuperBlock. This may be bigger than
    // |metadata_size_| if there was extra space pre allocated for allowing fvm growing.
    size_t metadata_allocated_size() const { return metadata_allocated_size_; }

    // Returns the number of addressable slices for the superblock, this is the number
    // of physical slices.
    size_t slice_count() const { return slice_count_; }

    // Returns the size of each slice in the described block.
    size_t slice_size() const { return slice_size_; }

    // Returns the offset of the given superblock. The first superblock is considered primary,
    // in terms of position.
    size_t GetSuperblockOffset(SuperblockType type) const {
        return (type == SuperblockType::kPrimary) ? 0 : metadata_allocated_size();
    }

    // Returns the offset from the start of the disk to beginning of |pslice| physical slice.
    // Note: pslice is 1-indexed.
    size_t GetSliceStart(size_t pslice) const {
        return 2 * metadata_allocated_size_ + (pslice - 1) * slice_size_;
    }

    // Returns the maximum number of slices that can be addressed from the maximum possible size
    // of the metatadata.
    size_t GetMaxAllocatableSlices() const {
        return (metadata_allocated_size() - kAllocTableOffset) / sizeof(SliceEntry);
    }

    // Returns the maximum number of slices that the allocated metadata can address for a given
    // |disk_size|.
    size_t GetMaxAddressableSlices(uint64_t disk_size) const {
        size_t slice_count =
            std::min(GetMaxAllocatableSlices(), UsableSlicesCount(disk_size, slice_size_));
        // Because the allocation thable is 1-indexed and pslices are 0 indexed on disk,
        // if the number of slices fit perfectly in the metadata, the allocated buffer won't be big
        // enough to address them all. This only happens when the rounded up block value happens to
        // match the disk size.
        // TODO(gevalentino): Fix underlying cause and remove workaround.
        if ((GetSliceStart(1) + slice_count * slice_size()) == metadata_allocated_size()) {
            slice_count--;
        }
        return slice_count;
    }

    // Returns the maximum partition size the current metadata can grow to.
    size_t GetMaxPartitionSize() const {
        return GetSliceStart(1) + GetMaxAllocatableSlices() * slice_size_;
    }

private:
    // Size in bytes of addressable metadata.
    size_t metadata_size_ = 0;

    // Size in bytes of the allocated size of metadata.
    size_t metadata_allocated_size_ = 0;

    // Number of addressable slices.
    size_t slice_count_ = 0;

    // Size of the slices.
    size_t slice_size_ = 0;
};

} // namespace fvm

#endif //  __cplusplus

__BEGIN_CDECLS

// Update's the metadata's hash field to accurately reflect
// the contents of metadata.
void fvm_update_hash(void* metadata, size_t metadata_size);

// Validate the FVM header information, and identify which
// copy of metadata (primary or backup) should be used for
// initial reading, if either.
//
// "out" is an optional output parameter which is equal to a
// valid copy of either metadata or backup on success.
zx_status_t fvm_validate_header(const void* metadata, const void* backup, size_t metadata_size,
                                const void** out);

__END_CDECLS

#endif //  __LIB_FVM_FORMAT_H__
