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

#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/assert.h>

#include <iomanip>
#include <limits>

#include <safemath/checked_math.h>

#include "src/storage/blobfs/blob_layout.h"
#include "src/storage/blobfs/format.h"

#ifdef __Fuchsia__
#include <fuchsia/hardware/block/c/fidl.h>
#include <fuchsia/hardware/block/volume/c/fidl.h>

#include "src/storage/fvm/client.h"
#endif

#include "src/storage/blobfs/common.h"

namespace blobfs {
namespace {

uint32_t GetBlobfsMajorVersionFromOptions(const FilesystemOptions& options) {
  if (options.blob_layout_format == BlobLayoutFormat::kCompactMerkleTreeAtEnd) {
    return kBlobfsCompactMerkleTreeVersion;
  }
  return 0x8;
}

bool CheckFilesystemAndDriverCompatibility(uint32_t major_version) {
  if (major_version == kBlobfsCurrentMajorVersion) {
    return true;
  }
  // Driver version 9 is compatible with filesystem version 8.
  if (major_version == 0x8 && kBlobfsCurrentMajorVersion == 0x9) {
    return true;
  }
  FX_LOGS(ERROR) << "Filesystem and Driver are incompatible. FS Version: " << std::setfill('0')
                 << std::setw(8) << std::hex << major_version
                 << ". Driver version: " << std::setw(8) << kBlobfsCurrentMajorVersion;
  return false;
}

}  // namespace

std::ostream& operator<<(std::ostream& stream, const Superblock& info) {
  return stream << "\ninfo.magic0: " << info.magic0 << "\ninfo.magic1: " << info.magic1
                << "\ninfo.major_version: " << info.major_version << "\ninfo.flags: " << info.flags
                << "\ninfo.block_size: " << info.block_size
                << "\ninfo.data_block_count: " << info.data_block_count
                << "\ninfo.journal_block_count: " << info.journal_block_count
                << "\ninfo.inode_count: " << info.inode_count
                << "\ninfo.alloc_block_count: " << info.alloc_block_count
                << "\ninfo.alloc_inode_count: " << info.alloc_inode_count
                << "\ninfo.slice_size: " << info.slice_size
                << "\ninfo.abm_slices: " << info.abm_slices
                << "\ninfo.ino_slices: " << info.ino_slices
                << "\ninfo.dat_slices: " << info.dat_slices
                << "\ninfo.journal_slices: " << info.journal_slices
                << "\ninfo.oldest_minor_version: " << info.oldest_minor_version;
}

// Validate the metadata for the superblock, given a maximum number of available blocks.
zx_status_t CheckSuperblock(const Superblock* info, uint64_t max, bool quiet) {
  if ((info->magic0 != kBlobfsMagic0) || (info->magic1 != kBlobfsMagic1)) {
    if (!quiet)
      FX_LOGS(ERROR) << "bad magic";
    return ZX_ERR_INVALID_ARGS;
  }
  if (!CheckFilesystemAndDriverCompatibility(info->major_version)) {
    if (!quiet)
      FX_LOGS(ERROR) << *info;
    return ZX_ERR_INVALID_ARGS;
  }
  if (info->block_size != kBlobfsBlockSize) {
    if (!quiet)
      FX_LOGS(ERROR) << "block_size " << info->block_size << " unsupported" << *info;
    return ZX_ERR_INVALID_ARGS;
  }

  if (info->data_block_count < kMinimumDataBlocks) {
    if (!quiet)
      FX_LOGS(ERROR) << "Not enough space for minimum data partition";
    return ZX_ERR_NO_SPACE;
  }

  if (info->inode_count == 0) {
    if (!quiet)
      FX_LOGS(ERROR) << "Node table is zero-sized";
    return ZX_ERR_NO_SPACE;
  }

#ifdef __Fuchsia__
  if ((info->flags & kBlobFlagClean) == 0) {
    if (!quiet)
      FX_LOGS(WARNING) << "filesystem in dirty state. Was not unmounted cleanly.";
  } else {
    if (!quiet)
      FX_LOGS(INFO) << "filesystem in clean state.";
  }
#endif

  // Determine the number of blocks necessary for the block map and node map.
  uint64_t total_inode_size;
  if (mul_overflow(info->inode_count, sizeof(Inode), &total_inode_size)) {
    if (!quiet)
      FX_LOGS(ERROR) << "Multiplication overflow";
    return ZX_ERR_OUT_OF_RANGE;
  }

  uint64_t node_map_size;
  if (mul_overflow(NodeMapBlocks(*info), kBlobfsBlockSize, &node_map_size)) {
    if (!quiet)
      FX_LOGS(ERROR) << "Multiplication overflow";
    return ZX_ERR_OUT_OF_RANGE;
  }

  if (total_inode_size != node_map_size) {
    if (!quiet)
      FX_LOGS(ERROR) << "Inode table block must be entirely filled";
    return ZX_ERR_BAD_STATE;
  }

  if (info->journal_block_count < kMinimumJournalBlocks) {
    if (!quiet)
      FX_LOGS(ERROR) << "Not enough space for minimum journal partition";
    return ZX_ERR_NO_SPACE;
  }

  if (TotalBlocks(*info) > max) {
    if (!quiet)
      FX_LOGS(ERROR) << "Too large for device (" << max << " blocks): " << *info;
    return ZX_ERR_INVALID_ARGS;
  }
  if (info->flags & kBlobFlagFVM) {
    const size_t blocks_per_slice = info->slice_size / info->block_size;

    // Ensure that we have enough room in the first slice for the backup superblock, too. We could,
    // in theory, support a backup superblock which span past the first slice, but it would be a lot
    // of work given the tight coupling between FVM/blobfs, and the many places which assume that
    // the superblocks both fit within a slice.
    if (blobfs::kBlobfsBlockSize * 2 > info->slice_size) {
      if (!quiet)
        FX_LOGS(ERROR) << "Slice size doesn't fit backup superblock" << *info;
      return ZX_ERR_INVALID_ARGS;
    }

    size_t abm_blocks_needed = BlockMapBlocks(*info);
    size_t abm_blocks_allocated = info->abm_slices * blocks_per_slice;
    if (abm_blocks_needed > abm_blocks_allocated) {
      if (!quiet)
        FX_LOGS(ERROR) << "Not enough slices for block bitmap" << *info;
      return ZX_ERR_INVALID_ARGS;
    } else if (abm_blocks_allocated + BlockMapStartBlock(*info) >= NodeMapStartBlock(*info)) {
      if (!quiet)
        FX_LOGS(ERROR) << "Block bitmap collides into node map" << *info;
      return ZX_ERR_INVALID_ARGS;
    }

    size_t ino_blocks_needed = NodeMapBlocks(*info);
    size_t ino_blocks_allocated = info->ino_slices * blocks_per_slice;
    if (ino_blocks_needed > ino_blocks_allocated) {
      if (!quiet)
        FX_LOGS(ERROR) << "Not enough slices for node map" << *info;
      return ZX_ERR_INVALID_ARGS;
    } else if (ino_blocks_allocated + NodeMapStartBlock(*info) >= DataStartBlock(*info)) {
      if (!quiet)
        FX_LOGS(ERROR) << "Node bitmap collides into data blocks" << *info;
      return ZX_ERR_INVALID_ARGS;
    }

    size_t dat_blocks_needed = DataBlocks(*info);
    size_t dat_blocks_allocated = info->dat_slices * blocks_per_slice;
    if (dat_blocks_needed < kStartBlockMinimum) {
      if (!quiet)
        FX_LOGS(ERROR) << "Partition too small; no space left for data blocks" << *info;
      return ZX_ERR_INVALID_ARGS;
    } else if (dat_blocks_needed > dat_blocks_allocated) {
      if (!quiet)
        FX_LOGS(ERROR) << "Not enough slices for data blocks" << *info;
      return ZX_ERR_INVALID_ARGS;
    } else if (dat_blocks_allocated + DataStartBlock(*info) >
               std::numeric_limits<uint32_t>::max()) {
      if (!quiet)
        FX_LOGS(ERROR) << "Data blocks overflow uint32" << *info;
      return ZX_ERR_INVALID_ARGS;
    }
  }
  return ZX_OK;
}

uint32_t CalculateVsliceCount(const Superblock& superblock) {
  return safemath::checked_cast<uint32_t>(1 + static_cast<uint64_t>(superblock.abm_slices) +
                                          static_cast<uint64_t>(superblock.ino_slices) +
                                          static_cast<uint64_t>(superblock.dat_slices) +
                                          static_cast<uint64_t>(superblock.journal_slices));
}

uint32_t BlocksRequiredForInode(uint64_t inode_count) {
  return safemath::checked_cast<uint32_t>(fbl::round_up(inode_count, kBlobfsInodesPerBlock) /
                                          kBlobfsInodesPerBlock);
}

uint32_t BlocksRequiredForBits(uint64_t bit_count) {
  return safemath::checked_cast<uint32_t>(fbl::round_up(bit_count, kBlobfsBlockBits) /
                                          kBlobfsBlockBits);
}

void InitializeSuperblockOptions(const FilesystemOptions& options, Superblock* info) {
  memset(info, 0x00, sizeof(*info));
  info->magic0 = kBlobfsMagic0;
  info->magic1 = kBlobfsMagic1;
  info->major_version = GetBlobfsMajorVersionFromOptions(options);
  info->flags = kBlobFlagClean;
  info->block_size = kBlobfsBlockSize;
  info->alloc_block_count = kStartBlockMinimum;
  info->alloc_inode_count = 0;
  info->oldest_minor_version = options.oldest_minor_version;
}

zx_status_t InitializeSuperblock(uint64_t block_count, const FilesystemOptions& options,
                                 Superblock* info) {
  InitializeSuperblockOptions(options, info);

  // Round up |inode_count| to use a block-aligned amount.
  info->inode_count = BlocksRequiredForInode(options.num_inodes) * kBlobfsInodesPerBlock;

  // Temporarily set the data_block_count to the total block_count so we can estimate the number
  // of pre-data blocks.
  info->data_block_count = block_count;

  // The result of DataStartBlock(info) is based on the current value of info.data_block_count.
  // As a result, the block bitmap may have slightly more space allocated than is necessary.
  size_t usable_blocks =
      JournalStartBlock(*info) < block_count ? block_count - JournalStartBlock(*info) : 0;

  if (usable_blocks < kMinimumDataBlocks + kMinimumJournalBlocks) {
    info->journal_block_count = 0;
    info->data_block_count = 0;
    return ZX_ERR_NO_SPACE;
  }

  info->journal_block_count = kMinimumJournalBlocks;
  info->data_block_count = block_count - DataStartBlock(*info);
  return ZX_OK;
}

BlobLayoutFormat GetBlobLayoutFormat(const Superblock& info) {
  if (info.major_version >= 0x9) {
    return BlobLayoutFormat::kCompactMerkleTreeAtEnd;
  }
  return BlobLayoutFormat::kDeprecatedPaddedMerkleTreeAtStart;
}

constexpr char kBlobVmoNamePrefix[] = "blob";
constexpr char kInactiveBlobVmoNamePrefix[] = "inactive-blob";

void FormatVmoName(const digest::Digest& digest, fbl::StringBuffer<ZX_MAX_NAME_LEN>* out,
                   const char* prefix) {
  out->Clear();
  out->AppendPrintf("%s-%.8s", prefix, digest.ToString().c_str());
}

void FormatBlobDataVmoName(const digest::Digest& digest, fbl::StringBuffer<ZX_MAX_NAME_LEN>* out) {
  FormatVmoName(digest, out, kBlobVmoNamePrefix);
}

void FormatInactiveBlobDataVmoName(const digest::Digest& digest,
                                   fbl::StringBuffer<ZX_MAX_NAME_LEN>* out) {
  FormatVmoName(digest, out, kInactiveBlobVmoNamePrefix);
}

}  // namespace blobfs
