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

#pragma once

#include <bitmap/raw-bitmap.h>
#include <bitmap/storage.h>
#include <digest/digest.h>
#include <digest/merkle-tree.h>
#include <fbl/algorithm.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/intrusive_wavl_tree.h>
#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_free_ptr.h>

#include <zircon/types.h>

#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>

#ifdef __Fuchsia__
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::VmoStorage>;
#else
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::DefaultStorage>;
#endif

// clang-format off

constexpr uint64_t kBlobstoreMagic0  = (0xac2153479e694d21ULL);
constexpr uint64_t kBlobstoreMagic1  = (0x985000d4d4d3d314ULL);
constexpr uint32_t kBlobstoreVersion = 0x00000003;

constexpr uint32_t kBlobstoreFlagClean      = 1;
constexpr uint32_t kBlobstoreFlagDirty      = 2;
constexpr uint32_t kBlobstoreFlagFVM        = 4;
constexpr uint32_t kBlobstoreBlockSize      = 8192;
constexpr uint32_t kBlobstoreBlockBits      = (kBlobstoreBlockSize * 8);
constexpr uint32_t kBlobstoreBlockMapStart  = 1;
constexpr uint32_t kBlobstoreInodeSize      = 64;
constexpr uint32_t kBlobstoreInodesPerBlock = (kBlobstoreBlockSize / kBlobstoreInodeSize);

constexpr size_t kFVMBlockMapStart  = 0x10000;
constexpr size_t kFVMNodeMapStart   = 0x20000;
constexpr size_t kFVMDataStart      = 0x30000;

// Notes:
// - block 0 is always allocated
// - inode 0 is never used, should be marked allocated but ignored

typedef struct {
    uint64_t magic0;
    uint64_t magic1;
    uint32_t version;
    uint32_t flags;
    uint32_t block_size;       // 8K typical
    uint64_t block_count;      // Number of data blocks in this area
    uint64_t inode_count;      // Number of blobs in this area
    uint64_t alloc_block_count; // Total number of allocated blocks
    uint64_t alloc_inode_count; // Total number of allocated blobs
    uint64_t blob_header_next; // Block containing next blobstore, or zero if this is the last one
    // The following flags are only valid with (flags & kBlobstoreFlagFVM):
    uint64_t slice_size;    // Underlying slice size
    uint64_t vslice_count;  // Number of underlying slices
    uint32_t abm_slices;    // Slices allocated to block bitmap
    uint32_t ino_slices;    // Slices allocated to node map
    uint32_t dat_slices;    // Slices allocated to file data section
} blobstore_info_t;

constexpr uint64_t BlockMapStartBlock(const blobstore_info_t& info) {
    if (info.flags & kBlobstoreFlagFVM) {
        return kFVMBlockMapStart;
    } else {
        return kBlobstoreBlockMapStart;
    }
}

constexpr uint64_t BlockMapBlocks(const blobstore_info_t& info) {
    return fbl::roundup(info.block_count, kBlobstoreBlockBits) / kBlobstoreBlockBits;
}

constexpr uint64_t NodeMapStartBlock(const blobstore_info_t& info) {
    // Node map immediately follows the block map
    if (info.flags & kBlobstoreFlagFVM) {
        return kFVMNodeMapStart;
    } else {
        return BlockMapStartBlock(info) + BlockMapBlocks(info);
    }
}

constexpr uint64_t NodeMapBlocks(const blobstore_info_t& info) {
    return fbl::roundup(info.inode_count, kBlobstoreInodesPerBlock) / kBlobstoreInodesPerBlock;
}

constexpr uint64_t DataStartBlock(const blobstore_info_t& info) {
    // Data immediately follows the node map
    if (info.flags & kBlobstoreFlagFVM) {
        return kFVMDataStart;
    } else {
        return NodeMapStartBlock(info) + NodeMapBlocks(info);
    }
}

constexpr uint64_t DataBlocks(const blobstore_info_t& info) {
    return info.block_count;
}

constexpr uint64_t TotalBlocks(const blobstore_info_t& info) {
    return BlockMapStartBlock(info) + BlockMapBlocks(info) + NodeMapBlocks(info) + DataBlocks(info);
}

// States of 'Blob' identified via start block.
constexpr uint64_t kStartBlockFree     = 0;
constexpr uint64_t kStartBlockReserved = 1;
constexpr uint64_t kStartBlockMinimum  = 2; // Smallest 'data' block possible

using digest::Digest;
typedef struct {
    uint8_t  merkle_root_hash[Digest::kLength];
    uint64_t start_block;
    uint64_t num_blocks;
    uint64_t blob_size;
    uint64_t reserved;
} blobstore_inode_t;

static_assert(sizeof(blobstore_inode_t) == kBlobstoreInodeSize,
              "Blobstore Inode size is wrong");
static_assert(kBlobstoreBlockSize % kBlobstoreInodeSize == 0,
              "Blobstore Inodes should fit cleanly within a blobstore block");

// Number of blocks reserved for the blob itself
constexpr uint64_t BlobDataBlocks(const blobstore_inode_t& blobNode) {
    return fbl::roundup(blobNode.blob_size, kBlobstoreBlockSize) / kBlobstoreBlockSize;
}

void* GetBlock(const RawBitmap& bitmap, uint32_t blkno);
void* GetBitBlock(const RawBitmap& bitmap, uint32_t* blkno_out, uint32_t bitno);
