/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <stddef.h>
#include <assert.h>
#include <string.h>
#include "testutil/testutil.h"
#include "nffs/nffs.h"
#include "nffs_priv.h"

struct nffs_hash_entry *
nffs_block_entry_alloc(void)
{
    struct nffs_hash_entry *entry;

    entry = os_memblock_get(&nffs_block_entry_pool);
    if (entry != NULL) {
        memset(entry, 0, sizeof *entry);
    }

    return entry;
}

void
nffs_block_entry_free(struct nffs_hash_entry *block_entry)
{
    assert(nffs_hash_id_is_block(block_entry->nhe_id));
    os_memblock_put(&nffs_block_entry_pool, block_entry);
}

/**
 * Allocates a block entry.  If allocation fails due to memory exhaustion,
 * garbage collection is performed and the allocation is retried.  This
 * process is repeated until allocation is successful or all areas have been
 * garbage collected.
 *
 * @param out_block_entry           On success, the address of the allocated
 *                                      block gets written here.
 *
 * @return                          0 on successful allocation;
 *                                  FS_ENOMEM on memory exhaustion;
 *                                  other nonzero on garbage collection error.
 */
int
nffs_block_entry_reserve(struct nffs_hash_entry **out_block_entry)
{
    int rc;

    do {
        *out_block_entry = nffs_block_entry_alloc();
    } while (nffs_misc_gc_if_oom(*out_block_entry, &rc));

    return rc;
}

/**
 * Reads a data block header from flash.
 *
 * @param area_idx              The index of the area to read from.
 * @param area_offset           The offset within the area to read from.
 * @param out_disk_block        On success, the block header is writteh here.
 *
 * @return                      0 on success;
 *                              FS_EOFFSET on an attempt to read an invalid
 *                                  address range;
 *                              FS_EHW on flash error;
 *                              FS_EUNEXP if the specified disk location does
 *                                  not contain a block.
 */
int
nffs_block_read_disk(uint8_t area_idx, uint32_t area_offset,
                     struct nffs_disk_block *out_disk_block)
{
    int rc;

    STATS_INC(nffs_stats, nffs_readcnt_block);
    rc = nffs_flash_read(area_idx, area_offset, out_disk_block,
                         sizeof *out_disk_block);
    if (rc != 0) {
        return rc;
    }
    if (!nffs_hash_id_is_block(out_disk_block->ndb_id)) {
        return FS_EUNEXP;
    }

    return 0;
}

/**
 * Writes the specified data block to a suitable location in flash.
 *
 * @param disk_block            Points to the disk block to write.
 * @param data                  The contents of the data block.
 * @param out_area_idx          On success, contains the index of the area
 *                                  written to.
 * @param out_area_offset       On success, contains the offset within the area
 *                                  written to.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_block_write_disk(const struct nffs_disk_block *disk_block,
                      const void *data,
                      uint8_t *out_area_idx, uint32_t *out_area_offset)
{
    uint32_t area_offset;
    uint8_t area_idx;
    int rc;

    rc = nffs_misc_reserve_space(sizeof *disk_block + disk_block->ndb_data_len,
                                &area_idx, &area_offset);
    if (rc != 0) {
        return rc;
    }

    rc = nffs_flash_write(area_idx, area_offset, disk_block,
                         sizeof *disk_block);
    if (rc != 0) {
        return rc;
    }

    if (disk_block->ndb_data_len > 0) {
        rc = nffs_flash_write(area_idx, area_offset + sizeof *disk_block,
                             data, disk_block->ndb_data_len);
        if (rc != 0) {
            return rc;
        }
    }

    *out_area_idx = area_idx;
    *out_area_offset = area_offset;

    ASSERT_IF_TEST(nffs_crc_disk_block_validate(disk_block, area_idx,
                                               area_offset) == 0);

    return 0;
}

static void
nffs_block_from_disk_no_ptrs(struct nffs_block *out_block,
                             const struct nffs_disk_block *disk_block)
{
    out_block->nb_seq = disk_block->ndb_seq;
    out_block->nb_inode_entry = NULL;
    out_block->nb_prev = NULL;
    out_block->nb_data_len = disk_block->ndb_data_len;
}

/**
 * Constructs a block representation from a disk record.  If the disk block
 * references other objects (inode or previous data block), the resulting block
 * object is populated with pointers to the referenced objects.  If the any
 * referenced objects are not present in the NFFS RAM representation, this
 * indicates file system corruption.  In this case, the resulting block is
 * populated with all valid references, and an FS_ECORRUPT code is returned.
 *
 * @param out_block             The resulting block is written here (regardless
 *                                  of this function's return code).
 * @param disk_block            The source disk record to convert.
 *
 * @return                      0 if the block was successfully constructed;
 *                              FS_ECORRUPT if one or more pointers could not
 *                                  be filled in due to file system corruption.
 */
static int
nffs_block_from_disk(struct nffs_block *out_block,
                     const struct nffs_disk_block *disk_block)
{
    int rc;

    rc = 0;

    nffs_block_from_disk_no_ptrs(out_block, disk_block);

    out_block->nb_inode_entry = nffs_hash_find_inode(disk_block->ndb_inode_id);
    if (out_block->nb_inode_entry == NULL) {
        rc = FS_ECORRUPT;
    }

    if (disk_block->ndb_prev_id != NFFS_ID_NONE) {
        out_block->nb_prev = nffs_hash_find_block(disk_block->ndb_prev_id);
        if (out_block->nb_prev == NULL) {
            rc = FS_ECORRUPT;
        }
    }

    return rc;
}

/**
 * Constructs a disk-representation of the specified data block.
 *
 * @param block                 The source block to convert.
 * @param out_disk_block        The disk block to write to.
 */
void
nffs_block_to_disk(const struct nffs_block *block,
                   struct nffs_disk_block *out_disk_block)
{
    assert(block->nb_inode_entry != NULL);

    memset(out_disk_block, 0, sizeof *out_disk_block);
    out_disk_block->ndb_id = block->nb_hash_entry->nhe_id;
    out_disk_block->ndb_seq = block->nb_seq;
    out_disk_block->ndb_inode_id =
        block->nb_inode_entry->nie_hash_entry.nhe_id;
    if (block->nb_prev == NULL) {
        out_disk_block->ndb_prev_id = NFFS_ID_NONE;
    } else {
        out_disk_block->ndb_prev_id = block->nb_prev->nhe_id;
    }
    out_disk_block->ndb_data_len = block->nb_data_len;
}

/**
 * Deletes the specified block entry from the nffs RAM representation.
 *
 * @param block_entry           The block entry to delete.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_block_delete_from_ram(struct nffs_hash_entry *block_entry)
{
    struct nffs_inode_entry *inode_entry;
    struct nffs_block block;
    int rc;

    if (nffs_hash_entry_is_dummy(block_entry)) {
        /*
         * it's very limited to what we can do here as the block doesn't have
         * any way to get to the inode via hash entry. Just delete the
         * block and return FS_ECORRUPT
         */
        nffs_hash_remove(block_entry);
        nffs_block_entry_free(block_entry);
        return FS_ECORRUPT;
    }

    rc = nffs_block_from_hash_entry(&block, block_entry);
    if (rc == 0 || rc == FS_ECORRUPT) {
        /* If file system corruption was detected, the resulting block is still
         * valid and can be removed from RAM.
         * Note that FS_CORRUPT can occur because the owning inode was not
         * found in the hash table - this can occur during the sweep where
         * the inodes were deleted ahead of the blocks.
         */
        inode_entry = block.nb_inode_entry;
        if (inode_entry != NULL &&
            inode_entry->nie_last_block_entry == block_entry) {

            inode_entry->nie_last_block_entry = block.nb_prev;
        }

        nffs_hash_remove(block_entry);
        nffs_block_entry_free(block_entry);
    }

    return rc;
}

/**
 * Determines if a particular block can be found in RAM by following a chain of
 * previous block pointers, starting with the specified hash entry.
 *
 * @param start                 The block entry at which to start the search.
 * @param sought_id             The ID of the block to search for.
 *
 * @return                      0 if the sought after ID was found;
 *                              FS_ENOENT if the ID was not found;
 *                              Other FS code on error.
 */
int
nffs_block_find_predecessor(struct nffs_hash_entry *start, uint32_t sought_id)
{
    struct nffs_hash_entry *entry;
    struct nffs_disk_block disk_block;
    uint32_t area_offset;
    uint8_t area_idx;
    int rc;

    entry = start;
    while (entry != NULL && entry->nhe_id != sought_id) {
        nffs_flash_loc_expand(entry->nhe_flash_loc, &area_idx, &area_offset);
        rc = nffs_block_read_disk(area_idx, area_offset, &disk_block);
        if (rc != 0) {
            return rc;
        }

        if (disk_block.ndb_prev_id == NFFS_ID_NONE) {
            entry = NULL;
        } else {
            entry = nffs_hash_find(disk_block.ndb_prev_id);
        }
    }

    if (entry == NULL) {
        rc = FS_ENOENT;
    } else {
        rc = 0;
    }

    return rc;
}

/**
 * Constructs a full data block representation from the specified minimal
 * block entry.  However, the resultant block's pointers are set to null,
 * rather than populated via hash table lookups.  This behavior is useful when
 * the RAM representation has not been fully constructed yet.
 *
 * @param out_block             On success, this gets populated with the data
 *                                  block information.
 * @param block_entry           The source block entry to convert.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_block_from_hash_entry_no_ptrs(struct nffs_block *out_block,
                                   struct nffs_hash_entry *block_entry)
{
    struct nffs_disk_block disk_block;
    uint32_t area_offset;
    uint8_t area_idx;
    int rc;

    assert(nffs_hash_id_is_block(block_entry->nhe_id));

    memset(out_block, 0, sizeof *out_block);

    if (nffs_hash_entry_is_dummy(block_entry)) {
        /*
         * We can't read this from disk so we'll be missing filling in anything
         * not already in inode_entry (e.g., prev_id).
         */
        out_block->nb_hash_entry = block_entry;
        return FS_ENOENT; /* let caller know it's a partial inode_entry */
    }

    nffs_flash_loc_expand(block_entry->nhe_flash_loc, &area_idx, &area_offset);
    rc = nffs_block_read_disk(area_idx, area_offset, &disk_block);
    if (rc != 0) {
        return rc;
    }

    out_block->nb_hash_entry = block_entry;
    nffs_block_from_disk_no_ptrs(out_block, &disk_block);

    return 0;
}

/**
 * Constructs a block representation from a minimal block hash entry.  If the
 * hash entry references other objects (inode or previous data block), the
 * resulting block object is populated with pointers to the referenced objects.
 * If the any referenced objects are not present in the NFFS RAM
 * representation, this indicates file system corruption.  In this case, the
 * resulting block is populated with all valid references, and an FS_ECORRUPT
 * code is returned.
 *
 * @param out_block             On success, this gets populated with the data
 *                                  block information.
 * @param block_entry           The source block entry to convert.
 *
 * @return                      0 on success;
 *                              FS_ECORRUPT if one or more pointers could not
 *                                  be filled in due to file system corruption;
 *                              FS_EOFFSET on an attempt to read an invalid
 *                                  address range;
 *                              FS_EHW on flash error;
 *                              FS_EUNEXP if the specified disk location does
 *                                  not contain a block.
 */
int
nffs_block_from_hash_entry(struct nffs_block *out_block,
                           struct nffs_hash_entry *block_entry)
{
    struct nffs_disk_block disk_block;
    uint32_t area_offset;
    uint8_t area_idx;
    int rc;

    assert(nffs_hash_id_is_block(block_entry->nhe_id));

    if (nffs_block_is_dummy(block_entry)) {
        out_block->nb_hash_entry = block_entry;
        out_block->nb_inode_entry = NULL;
        out_block->nb_prev = NULL;
        /*
         * Dummy block added when inode was read in before real block
         * (see nffs_restore_inode()). Return success (because there's 
         * too many places that ned to check for this,
         * but it's the responsibility fo the upstream code to check
         * whether this is still a dummy entry.  XXX
         */
        return 0;
        /*return FS_ENOENT;*/
    }
    nffs_flash_loc_expand(block_entry->nhe_flash_loc, &area_idx, &area_offset);
    rc = nffs_block_read_disk(area_idx, area_offset, &disk_block);
    if (rc != 0) {
        return rc;
    }

    out_block->nb_hash_entry = block_entry;
    rc = nffs_block_from_disk(out_block, &disk_block);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
nffs_block_read_data(const struct nffs_block *block, uint16_t offset,
                     uint16_t length, void *dst)
{
    uint32_t area_offset;
    uint8_t area_idx;
    int rc;

    nffs_flash_loc_expand(block->nb_hash_entry->nhe_flash_loc,
                         &area_idx, &area_offset);
    area_offset += sizeof (struct nffs_disk_block);
    area_offset += offset;

    STATS_INC(nffs_stats, nffs_readcnt_data);
    rc = nffs_flash_read(area_idx, area_offset, dst, length);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
nffs_block_is_dummy(struct nffs_hash_entry *entry)
{
    return (entry->nhe_flash_loc == NFFS_FLASH_LOC_NONE);
}
