// 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 <errno.h>
#include <inttypes.h>
#include <sys/ioctl.h>

#include "fvm/container.h"

#if defined(__APPLE__)
#include <sys/disk.h>
#define IOCTL_GET_BLOCK_COUNT DKIOCGETBLOCKCOUNT
#endif

#if defined(__linux__)
#include <linux/fs.h>
#define IOCTL_GET_BLOCK_COUNT BLKGETSIZE
#endif

zx_status_t FvmContainer::Create(const char* path, size_t slice_size, off_t offset, off_t length,
                                 fbl::unique_ptr<FvmContainer>* out) {
    fbl::AllocChecker ac;
    fbl::unique_ptr<FvmContainer> fvmContainer(new (&ac) FvmContainer(path, slice_size, offset,
                                                                      length));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status;
    if ((status = fvmContainer->Init()) != ZX_OK) {
        return status;
    }

    *out = fbl::move(fvmContainer);
    return ZX_OK;
}

FvmContainer::FvmContainer(const char* path, size_t slice_size, off_t offset, off_t length)
    : Container(slice_size), valid_(false), disk_offset_(offset), disk_size_(length),
      vpart_hint_(1), pslice_hint_(1) {
    fd_.reset(open(path, O_RDWR, 0644));
    if (!fd_) {
        if (errno == ENOENT) {
            fd_.reset(open(path, O_RDWR | O_CREAT | O_EXCL, 0644));

            if (!fd_) {
                fprintf(stderr, "Failed to create path %s\n", path);
                exit(-1);
            }

            xprintf("Created path %s\n", path);
        } else {
            fprintf(stderr, "Failed to open path %s: %s\n", path, strerror(errno));
            exit(-1);
        }
    }

    struct stat s;
    if (fstat(fd_.get(), &s) < 0) {
        fprintf(stderr, "Failed to stat %s\n", path);
        exit(-1);
    }

    uint64_t size = s.st_size;

    if (S_ISBLK(s.st_mode)) {
        uint64_t block_count;
        if (ioctl(fd_.get(), IOCTL_GET_BLOCK_COUNT, &block_count) >= 0) {
            size = block_count * 512;
        }
    }

    if (size < disk_offset_ + disk_size_) {
        fprintf(stderr, "Invalid file size %" PRIu64 " for specified offset+length\n", size);
        exit(-1);
    }

    // Even if disk size is 0, this will default to at least FVM_BLOCK_SIZE
    metadata_size_ = fvm::MetadataSize(disk_size_, slice_size_);

    fbl::AllocChecker ac;
    metadata_.reset(new (&ac) uint8_t[metadata_size_ * 2]);
    if (!ac.check()) {
        fprintf(stderr, "Unable to acquire resources for metadata\n");
        exit(-1);
    }

    // Clear entire primary copy of metadata
    memset(metadata_.get(), 0, metadata_size_);

    // If Container already exists, read metadata from disk.
    if (disk_size_ > 0) {
        if (lseek(fd_.get(), disk_offset_, SEEK_SET) < 0) {
            fprintf(stderr, "Seek reset failed\n");
            exit(-1);
        }

        ssize_t rd = read(fd_.get(), metadata_.get(), metadata_size_ * 2);
        if (rd != static_cast<ssize_t>(metadata_size_ * 2)) {
            fprintf(stderr, "Metadata read failed: expected %ld, actual %ld\n", metadata_size_, rd);
            exit(-1);
        }

        const void* backup = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(metadata_.get()) +
                                                     metadata_size_);

        // For now we always assume that primary metadata is primary
        if (fvm_validate_header(metadata_.get(), backup, metadata_size_, nullptr) == ZX_OK) {
            valid_ = true;

            if (memcmp(metadata_.get(), backup, metadata_size_)) {
                fprintf(stderr, "Warning: primary and backup metadata do not match\n");
            }
        }
    }
}

FvmContainer::~FvmContainer() = default;

zx_status_t FvmContainer::Init() {
    // Clear entire primary copy of metadata
    memset(metadata_.get(), 0, metadata_size_);

    // Superblock
    fvm::fvm_t* sb = SuperBlock();
    sb->magic = FVM_MAGIC;
    sb->version = FVM_VERSION;
    sb->pslice_count = (disk_size_ - metadata_size_ * 2) / slice_size_;
    sb->slice_size = slice_size_;
    sb->fvm_partition_size = disk_size_;
    sb->vpartition_table_size = fvm::kVPartTableLength;
    sb->allocation_table_size = fvm::AllocTableLength(disk_size_, slice_size_);
    sb->generation = 0;

    if (sb->pslice_count == 0) {
        return ZX_ERR_NO_SPACE;
    }

    dirty_ = true;
    valid_ = true;

    xprintf("fvm_init: Success\n");
    xprintf("fvm_init: Slice Count: %" PRIu64 ", size: %" PRIu64 "\n", sb->pslice_count, sb->slice_size);
    xprintf("fvm_init: Vpart offset: %zu, length: %zu\n",
           fvm::kVPartTableOffset, fvm::kVPartTableLength);
    xprintf("fvm_init: Atable offset: %zu, length: %zu\n",
           fvm::kAllocTableOffset, fvm::AllocTableLength(disk_size_, slice_size_));
    xprintf("fvm_init: Backup meta starts at: %zu\n",
           fvm::BackupStart(disk_size_, slice_size_));
    xprintf("fvm_init: Slices start at %zu, there are %zu of them\n",
           fvm::SlicesStart(disk_size_, slice_size_),
           fvm::UsableSlicesCount(disk_size_, slice_size_));
    return ZX_OK;
}

zx_status_t FvmContainer::Verify() const {
    CheckValid();
    const void* backup = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(metadata_.get()) +
                                                 metadata_size_);

    if (fvm_validate_header(metadata_.get(), backup, metadata_size_, nullptr) != ZX_OK) {
        fprintf(stderr, "Failed to validate header\n");
        return ZX_ERR_BAD_STATE;
    }

    fvm::fvm_t* sb = SuperBlock();

    xprintf("Total size is %zu\n", disk_size_);
    xprintf("Metadata size is %zu\n", metadata_size_);
    xprintf("Slice size is %" PRIu64 "\n", sb->slice_size);
    xprintf("Slice count is %" PRIu64 "\n", sb->pslice_count);

    off_t start = 0;
    off_t end = disk_offset_ + metadata_size_ * 2;
    size_t slice_index = 1;
    for (size_t vpart_index = 1; vpart_index < FVM_MAX_ENTRIES; ++vpart_index) {
        fvm::vpart_entry_t* vpart = nullptr;
        start = end;

        zx_status_t status;
        if ((status = GetPartition(vpart_index, &vpart)) != ZX_OK) {
            return status;
        }

        if (vpart->slices == 0) {
            break;
        }

        fbl::Vector<size_t> extent_lengths;
        size_t last_vslice = 0;

        for (; slice_index <= sb->pslice_count; ++slice_index) {
            fvm::slice_entry_t* slice = nullptr;
            if ((status = GetSlice(slice_index, &slice)) != ZX_OK) {
                return status;
            }

            if (slice->vpart != vpart_index) {
                break;
            }

            end += slice_size_;

            if (slice->vslice == last_vslice + 1) {
                extent_lengths[extent_lengths.size()-1] += slice_size_;
            } else {
                extent_lengths.push_back(slice_size_);
            }

            last_vslice = slice->vslice;
        }

        disk_format_t part;
        if ((status = Format::Detect(fd_.get(), start, &part)) != ZX_OK) {
            return status;
        }

        fbl::unique_fd dupfd(dup(fd_.get()));
        if (!dupfd) {
            fprintf(stderr, "Failed to duplicate fd\n");
            return ZX_ERR_INTERNAL;
        }

        if ((status = Format::Check(fbl::move(dupfd), start, end, extent_lengths, part)) != ZX_OK) {
            fprintf(stderr, "%s fsck returned an error.\n", vpart->name);
            return status;
        }

        printf("Found valid %s partition\n", vpart->name);
    }

    return ZX_OK;
}

zx_status_t FvmContainer::Commit() {
    if (!dirty_) {
        fprintf(stderr, "Commit: Nothing to write\n");
        return ZX_OK;
    }

    // If the FVM container has just been created, truncate it to an appropriate size
    if (disk_size_ == 0) {
        if (partitions_.is_empty()) {
            fprintf(stderr, "Cannot create new FVM container with 0 partitions\n");
            return ZX_ERR_INVALID_ARGS;
        }

        size_t required_size = 0;
        for (unsigned i = 0; i < partitions_.size(); i++) {
            required_size += partitions_[i].slice_count * slice_size_;
        }

        size_t total_size = required_size;
        size_t metadata_size = 0;

        while (total_size - (metadata_size * 2) < required_size || metadata_size < metadata_size_) {
            total_size = required_size + (metadata_size * 2);
            metadata_size = fvm::MetadataSize(total_size, slice_size_);
        }

        zx_status_t status;
        if ((status = GrowMetadata(metadata_size)) != ZX_OK) {
            return status;
        }

        if (ftruncate(fd_.get(), total_size) != 0) {
            fprintf(stderr, "Failed to truncate fvm container");
            return ZX_ERR_IO;
        }

        struct stat s;
        if (fstat(fd_.get(), &s) < 0) {
            fprintf(stderr, "Failed to stat container\n");
            return ZX_ERR_IO;
        }

        disk_size_ = s.st_size;

        if (disk_size_ != total_size) {
            fprintf(stderr, "Truncated to incorrect size\n");
            return ZX_ERR_IO;
        }

        fvm::fvm_t* sb = SuperBlock();
        sb->pslice_count = (disk_size_ - metadata_size_ * 2) / slice_size_;
        sb->fvm_partition_size = disk_size_;
        sb->allocation_table_size = fvm::AllocTableLength(disk_size_, slice_size_);
    }

    fvm_update_hash(metadata_.get(), metadata_size_);

    if (lseek(fd_.get(), disk_offset_, SEEK_SET) < 0) {
        fprintf(stderr, "Error seeking disk\n");
        return ZX_ERR_IO;
    }

    if (write(fd_.get(), metadata_.get(), metadata_size_) != static_cast<ssize_t>(metadata_size_)) {
        fprintf(stderr, "Error writing metadata to disk\n");
        return ZX_ERR_IO;
    }

    if (write(fd_.get(), metadata_.get(), metadata_size_) != static_cast<ssize_t>(metadata_size_)) {
        fprintf(stderr, "Error writing metadata to disk\n");
        return ZX_ERR_IO;
    }

    for (unsigned i = 0; i < partitions_.size(); i++) {
        zx_status_t status;
        if ((status = WritePartition(i)) != ZX_OK) {
            return status;
        }
    }

    xprintf("Successfully wrote FVM data to disk\n");
    return ZX_OK;
}

size_t FvmContainer::SliceSize() const {
    CheckValid();
    return slice_size_;
}

zx_status_t FvmContainer::AddPartition(const char* path, const char* type_name) {
    fbl::unique_ptr<Format> format;
    zx_status_t status;
    if ((status = Format::Create(path, type_name, &format)) != ZX_OK) {
        fprintf(stderr, "Failed to initialize partition\n");
        return status;
    }

    uint8_t guid[FVM_GUID_LEN];
    uint8_t type[FVM_GUID_LEN];
    char name[FVM_NAME_LEN];
    format->Guid(guid);
    format->Type(type);
    format->Name(name);
    uint32_t vpart_index;
    if ((status = AllocatePartition(type, guid, name, 1, &vpart_index)) != ZX_OK) {
        return status;
    }

    if ((status = format->MakeFvmReady(SliceSize(), vpart_index)) != ZX_OK) {
        return status;
    }

    uint32_t slice_count = 0;
    if ((status = format->GetSliceCount(&slice_count)) != ZX_OK) {
        return status;
    }

    // If allocated metadata is too small, grow it to an appropriate size
    size_t required_size = fvm::kAllocTableOffset + (pslice_hint_ + slice_count)
                           * sizeof(fvm::slice_entry_t);
    if ((status = GrowMetadata(required_size)) != ZX_OK) {
        return status;
    }

    // Allocate all slices for this partition
    uint32_t pslice_start = 0;
    uint32_t pslice_total = 0;
    unsigned extent_index = 0;
    while (true) {
        vslice_info_t vslice_info;
        zx_status_t status;
        if ((status = format->GetVsliceRange(extent_index, &vslice_info)) != ZX_OK) {
            if (status == ZX_ERR_OUT_OF_RANGE) {
                break;
            }
            return status;
        }

        uint32_t vslice = vslice_info.vslice_start / format->BlocksPerSlice();

        for (unsigned i = 0; i < vslice_info.slice_count; i++) {
            uint32_t pslice;

            if ((status = AllocateSlice(format->VpartIndex(), vslice + i, &pslice)) != ZX_OK) {
                return status;
            }

            if (!pslice_start) {
                pslice_start = pslice;
            }

            // On a new FVM container, pslice allocation is expected to be contiguous.
            if (pslice != pslice_start + pslice_total) {
                fprintf(stderr, "Unexpected error during slice allocation\n");
                return ZX_ERR_INTERNAL;
            }

            pslice_total++;
        }

        extent_index++;
    }

    partition_info_t partition;
    partition.format = fbl::move(format);
    partition.vpart_index = vpart_index;
    partition.pslice_start = pslice_start;
    partition.slice_count = slice_count;
    partitions_.push_back(fbl::move(partition));
    return ZX_OK;
}

void FvmContainer::CheckValid() const {
    if (!valid_) {
        fprintf(stderr, "Error: FVM is invalid\n");
        exit(-1);
    }
}

zx_status_t FvmContainer::GrowMetadata(size_t new_size) {
    if (new_size <= metadata_size_) {
        return ZX_OK;
    } else if (disk_size_ > 0) {
        fprintf(stderr, "Cannot grow metadata for disk with established size\n");
        return ZX_ERR_ACCESS_DENIED;
    }

    xprintf("Growing metadata from %zu to %zu\n", metadata_size_, new_size);
    fbl::AllocChecker ac;
    fbl::unique_ptr<uint8_t[]> new_metadata(new (&ac) uint8_t[new_size * 2]);
    if (!ac.check()) {
        fprintf(stderr, "Unable to acquire resources for new metadata\n");
        return ZX_ERR_NO_MEMORY;
    }

    memcpy(new_metadata.get(), metadata_.get(), metadata_size_);
    memset(new_metadata.get() + metadata_size_, 0, new_size - metadata_size_);

    metadata_ = fbl::move(new_metadata);
    metadata_size_ = new_size;
    return ZX_OK;
}

zx_status_t FvmContainer::AllocatePartition(uint8_t* type, uint8_t* guid, const char* name,
                                            uint32_t slices, uint32_t* vpart_index) {
    CheckValid();
    for (unsigned index = vpart_hint_; index < FVM_MAX_ENTRIES; index++) {
        zx_status_t status;
        fvm::vpart_entry_t* vpart = nullptr;
        if ((status = GetPartition(index, &vpart)) != ZX_OK) {
            fprintf(stderr, "Failed to retrieve partition %u\n", index);
            return status;
        }

        // Make sure this vpartition has not already been allocated
        if (vpart->slices == 0) {
            vpart->init(type, guid, slices, name, 0);
            vpart_hint_ = index + 1;
            dirty_ = true;
            *vpart_index = index;
            return ZX_OK;
        }
    }

    fprintf(stderr, "Unable to find any free partitions\n");
    return ZX_ERR_INTERNAL;
}

zx_status_t FvmContainer::AllocateSlice(uint32_t vpart, uint32_t vslice, uint32_t* pslice) {
    CheckValid();
    fvm::fvm_t* sb = SuperBlock();

    for (uint32_t index = pslice_hint_; index < sb->pslice_count; index++) {
        zx_status_t status;
        fvm::slice_entry_t* slice = nullptr;
        if ((status = GetSlice(index, &slice)) != ZX_OK) {
            fprintf(stderr, "Failed to retrieve slice %u\n", index);
            return status;
        }

        if (slice->vpart != FVM_SLICE_FREE) {
            continue;
        }

        pslice_hint_ = index + 1;

        slice->vpart = vpart & VPART_MAX;
        slice->vslice = vslice & VSLICE_MAX;
        dirty_ = true;
        *pslice = index;
        return ZX_OK;
    }

    fprintf(stderr, "Unable to find any free slices\n");
    return ZX_ERR_INTERNAL;
}

zx_status_t FvmContainer::GetPartition(size_t index, fvm::vpart_entry_t** out) const {
    CheckValid();

    if (index < 1 || index > FVM_MAX_ENTRIES) {
        return ZX_ERR_OUT_OF_RANGE;
    }

    uintptr_t metadata_start = reinterpret_cast<uintptr_t>(metadata_.get());
    uintptr_t offset = static_cast<uintptr_t>(fvm::kVPartTableOffset +
                                                  index * sizeof(fvm::vpart_entry_t));
    *out = reinterpret_cast<fvm::vpart_entry_t*>(metadata_start + offset);
    return ZX_OK;
}

zx_status_t FvmContainer::GetSlice(size_t index, fvm::slice_entry_t** out) const {
    CheckValid();

    if (index < 1 || index > SuperBlock()->pslice_count) {
        return ZX_ERR_OUT_OF_RANGE;
    }

    uintptr_t metadata_start = reinterpret_cast<uintptr_t>(metadata_.get());
    uintptr_t offset = static_cast<uintptr_t>(fvm::kAllocTableOffset +
                                              index * sizeof(fvm::slice_entry_t));
    *out = reinterpret_cast<fvm::slice_entry_t*>(metadata_start + offset);
    return ZX_OK;
}

zx_status_t FvmContainer::WritePartition(unsigned part_index) {
    CheckValid();
    if (part_index > partitions_.size()) {
        fprintf(stderr, "Error: Tried to access partition %u / %zu\n",
                part_index, partitions_.size());
        return ZX_ERR_OUT_OF_RANGE;
    }

    unsigned extent_index = 0;
    partition_info_t* partition = &partitions_[part_index];
    Format* format = partition->format.get();
    uint32_t pslice_start = partition->pslice_start;

    while (true) {
        zx_status_t status;
        if ((status = WriteExtent(extent_index++, format, &pslice_start)) != ZX_OK) {
            if (status != ZX_ERR_OUT_OF_RANGE) {
                return status;
            }

            return ZX_OK;
        }
    }
}

zx_status_t FvmContainer::WriteExtent(unsigned extent_index, Format* format, uint32_t* pslice) {
    vslice_info_t vslice_info;
    zx_status_t status;
    if ((status = format->GetVsliceRange(extent_index, &vslice_info)) != ZX_OK) {
        return status;
    }

    // Write each slice in the given extent
    uint32_t current_block = 0;
    for (unsigned i = 0; i < vslice_info.slice_count; i++) {
        // Write each block in this slice
        for (uint32_t j = 0; j < format->BlocksPerSlice(); j++) {
            // If we have gone beyond the blocks written to partition file, write empty block
            if (current_block >= vslice_info.block_count) {
                if (!vslice_info.zero_fill) {
                    break;
                }

                format->EmptyBlock();
            } else {
                if ((status = format->FillBlock(vslice_info.block_offset + current_block)) != ZX_OK) {
                    fprintf(stderr, "Failed to read block from minfs\n");
                    return status;
                }

                current_block++;
            }

            if ((status = WriteData(*pslice, j, format->BlockSize(), format->Data())) != ZX_OK) {
                fprintf(stderr, "Failed to write data to FVM\n");
                return status;
            }
        }
        (*pslice)++;
    }

    return ZX_OK;
}

zx_status_t FvmContainer::WriteData(uint32_t pslice, uint32_t block_offset, size_t block_size,
                                    void* data) {
    CheckValid();

    if (block_offset * block_size > slice_size_) {
        fprintf(stderr, "Not enough space in slice\n");
        return ZX_ERR_OUT_OF_RANGE;
    }

    if (lseek(fd_.get(), disk_offset_ + fvm::SliceStart(disk_size_, slice_size_, pslice) +
                block_offset * block_size, SEEK_SET) < 0) {
        return ZX_ERR_BAD_STATE;
    }

    ssize_t r = write(fd_.get(), data, block_size);
    if (r != block_size) {
        fprintf(stderr, "Failed to write data to FVM\n");
        return ZX_ERR_BAD_STATE;
    }

    return ZX_OK;
}

fvm::fvm_t* FvmContainer::SuperBlock() const {
    return static_cast<fvm::fvm_t*>((void*)metadata_.get());
}
