/*
 * 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 <assert.h>
#include <string.h>
#include "nffs/nffs.h"
#include "nffs_priv.h"

TAILQ_HEAD(nffs_cache_inode_list, nffs_cache_inode);
static struct nffs_cache_inode_list nffs_cache_inode_list =
    TAILQ_HEAD_INITIALIZER(nffs_cache_inode_list);

static void nffs_cache_reclaim_blocks(void);

static struct nffs_cache_block *
nffs_cache_block_alloc(void)
{
    struct nffs_cache_block *entry;

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

    return entry;
}

static void
nffs_cache_block_free(struct nffs_cache_block *entry)
{
    if (entry != NULL) {
        os_memblock_put(&nffs_cache_block_pool, entry);
    }
}

static struct nffs_cache_block *
nffs_cache_block_acquire(void)
{
    struct nffs_cache_block *cache_block;

    cache_block = nffs_cache_block_alloc();
    if (cache_block == NULL) {
        nffs_cache_reclaim_blocks();
        cache_block = nffs_cache_block_alloc();
    }

    assert(cache_block != NULL);

    return cache_block;
}

static int
nffs_cache_block_populate(struct nffs_cache_block *cache_block,
                          struct nffs_hash_entry *block_entry,
                          uint32_t end_offset)
{
    int rc;

    rc = nffs_block_from_hash_entry(&cache_block->ncb_block, block_entry);
    if (rc != 0) {
        return rc;
    }

    cache_block->ncb_file_offset = end_offset -
                                   cache_block->ncb_block.nb_data_len;

    return 0;
}

static struct nffs_cache_inode *
nffs_cache_inode_alloc(void)
{
    struct nffs_cache_inode *entry;

    entry = os_memblock_get(&nffs_cache_inode_pool);
    if (entry != NULL) {
        memset(entry, 0, sizeof *entry);
        TAILQ_INIT(&entry->nci_block_list);
    }

    return entry;
}

static void
nffs_cache_inode_free_blocks(struct nffs_cache_inode *cache_inode)
{
    struct nffs_cache_block *cache_block;

    while ((cache_block = TAILQ_FIRST(&cache_inode->nci_block_list)) != NULL) {
        TAILQ_REMOVE(&cache_inode->nci_block_list, cache_block, ncb_link);
        nffs_cache_block_free(cache_block);
    }
}

static void
nffs_cache_inode_free(struct nffs_cache_inode *entry)
{
    if (entry != NULL) {
        nffs_cache_inode_free_blocks(entry);
        os_memblock_put(&nffs_cache_inode_pool, entry);
    }
}

static struct nffs_cache_inode *
nffs_cache_inode_acquire(void)
{
    struct nffs_cache_inode *entry;

    entry = nffs_cache_inode_alloc();
    if (entry == NULL) {
        entry = TAILQ_LAST(&nffs_cache_inode_list, nffs_cache_inode_list);
        assert(entry != NULL);

        TAILQ_REMOVE(&nffs_cache_inode_list, entry, nci_link);
        nffs_cache_inode_free(entry);

        entry = nffs_cache_inode_alloc();
    }

    assert(entry != NULL);

    return entry;
}

static int
nffs_cache_inode_populate(struct nffs_cache_inode *cache_inode,
                         struct nffs_inode_entry *inode_entry)
{
    int rc;

    memset(cache_inode, 0, sizeof *cache_inode);

    rc = nffs_inode_from_entry(&cache_inode->nci_inode, inode_entry);
    if (rc != 0) {
        return rc;
    }

    rc = nffs_inode_calc_data_length(cache_inode->nci_inode.ni_inode_entry,
                                     &cache_inode->nci_file_size);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

/**
 * Retrieves the block entry corresponding to the last cached block in the
 * specified inode's list.  If the inode has no cached blocks, this function
 * returns null.
 */
static struct nffs_hash_entry *
nffs_cache_inode_last_entry(struct nffs_cache_inode *cache_inode)
{
    struct nffs_cache_block *cache_block;

    if (TAILQ_EMPTY(&cache_inode->nci_block_list)) {
        return NULL;
    }

    cache_block = TAILQ_LAST(&cache_inode->nci_block_list,
                             nffs_cache_block_list);
    return cache_block->ncb_block.nb_hash_entry;
}

static struct nffs_cache_inode *
nffs_cache_inode_find(const struct nffs_inode_entry *inode_entry)
{
    struct nffs_cache_inode *cur;

    TAILQ_FOREACH(cur, &nffs_cache_inode_list, nci_link) {
        if (cur->nci_inode.ni_inode_entry == inode_entry) {
            return cur;
        }
    }

    return NULL;
}

void
nffs_cache_inode_range(const struct nffs_cache_inode *cache_inode,
                      uint32_t *out_start, uint32_t *out_end)
{
    struct nffs_cache_block *cache_block;

    cache_block = TAILQ_FIRST(&cache_inode->nci_block_list);
    if (cache_block == NULL) {
        *out_start = 0;
        *out_end = 0;
        return;
    }

    *out_start = cache_block->ncb_file_offset;

    cache_block = TAILQ_LAST(&cache_inode->nci_block_list,
                             nffs_cache_block_list);
    *out_end = cache_block->ncb_file_offset +
               cache_block->ncb_block.nb_data_len;
}

static void
nffs_cache_reclaim_blocks(void)
{
    struct nffs_cache_inode *cache_inode;

    TAILQ_FOREACH_REVERSE(cache_inode, &nffs_cache_inode_list,
                          nffs_cache_inode_list, nci_link) {
        if (!TAILQ_EMPTY(&cache_inode->nci_block_list)) {
            nffs_cache_inode_free_blocks(cache_inode);
            return;
        }
    }

    assert(0);
}

void
nffs_cache_inode_delete(const struct nffs_inode_entry *inode_entry)
{
    struct nffs_cache_inode *entry;

    entry = nffs_cache_inode_find(inode_entry);
    if (entry == NULL) {
        return;
    }

    TAILQ_REMOVE(&nffs_cache_inode_list, entry, nci_link);
    nffs_cache_inode_free(entry);
}

int
nffs_cache_inode_ensure(struct nffs_cache_inode **out_cache_inode,
                        struct nffs_inode_entry *inode_entry)
{
    struct nffs_cache_inode *cache_inode;
    int rc;

    cache_inode = nffs_cache_inode_find(inode_entry);
    if (cache_inode != NULL) {
        rc = 0;
        goto done;
    }

    cache_inode = nffs_cache_inode_acquire();
    rc = nffs_cache_inode_populate(cache_inode, inode_entry);
    if (rc != 0) {
        goto done;
    }

    TAILQ_INSERT_HEAD(&nffs_cache_inode_list, cache_inode, nci_link);

    rc = 0;

done:
    if (rc == 0) {
        *out_cache_inode = cache_inode;
    } else {
        nffs_cache_inode_free(cache_inode);
        *out_cache_inode = NULL;
    }
    return rc;
}

/**
 * Recaches all cached inodes.  All cached blocks are deleted from the cache
 * during this operation.  This function should be called after garbage
 * collection occurs to ensure the cache is consistent.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_cache_inode_refresh(void)
{
    struct nffs_cache_inode *cache_inode;
    struct nffs_inode_entry *inode_entry;
    int rc;

    TAILQ_FOREACH(cache_inode, &nffs_cache_inode_list, nci_link) {
        /* Clear entire block list. */
        nffs_cache_inode_free_blocks(cache_inode);

        inode_entry = cache_inode->nci_inode.ni_inode_entry;
        rc = nffs_inode_from_entry(&cache_inode->nci_inode, inode_entry);
        if (rc != 0) {
            return rc;
        }

        /* File size remains valid. */
    }

    return 0;
}

static void
nffs_cache_log_block(struct nffs_cache_inode *cache_inode,
                     struct nffs_cache_block *cache_block)
{
    NFFS_LOG(DEBUG, "id=%u inode=%u flash_off=0x%08x "
                    "file_off=%u len=%d (entry=%p)\n",
             (unsigned int)cache_block->ncb_block.nb_hash_entry->nhe_id,
             (unsigned int)cache_inode->nci_inode.ni_inode_entry->nie_hash_entry.nhe_id,
             (unsigned int)cache_block->ncb_block.nb_hash_entry->nhe_flash_loc,
             (unsigned int)cache_block->ncb_file_offset,
             cache_block->ncb_block.nb_data_len,
             cache_block->ncb_block.nb_hash_entry);
}

static void
nffs_cache_log_insert_block(struct nffs_cache_inode *cache_inode,
                            struct nffs_cache_block *cache_block,
                            int tail)
{
    NFFS_LOG(DEBUG, "caching block (%s): ", tail ? "tail" : "head");
    nffs_cache_log_block(cache_inode, cache_block);
}

void
nffs_cache_insert_block(struct nffs_cache_inode *cache_inode,
                        struct nffs_cache_block *cache_block,
                        int tail)
{
    if (tail) {
        TAILQ_INSERT_TAIL(&cache_inode->nci_block_list, cache_block, ncb_link);
    } else {
        TAILQ_INSERT_HEAD(&cache_inode->nci_block_list, cache_block, ncb_link);
    }

    nffs_cache_log_insert_block(cache_inode, cache_block, tail);
}

/**
 * Finds the data block containing the specified offset within a file inode.
 * If the block is not yet cached, it gets cached as a result of this
 * operation.  This function modifies the inode's cached block list according
 * to the following procedure:
 *
 *  1. If none of the owning inode's blocks are currently cached, allocate a
 *     cached block entry and insert it into the inode's list.
 *  2. Else if the requested file offset is less than that of the first cached
 *     block, bridge the gap between the inode's sequence of cached blocks and
 *     the block that now needs to be cached.  This is accomplished by caching
 *     each block in the gap, finishing with the requested block.
 *  3. Else (the requested offset is beyond the end of the cache),
 *      a. If the requested offset belongs to the block that immediately
 *         follows the end of the cache, cache the block and append it to the
 *         list.
 *      b. Else, clear the cache, and populate it with the single entry
 *         corresponding to the requested block.
 *
 * @param cache_inode           The cached file inode to seek within.
 * @param seek_offset           The file offset to seek to.
 * @param out_cache_block       On success, the requested cached block gets
 *                                  written here; pass null if you don't need
 *                                  this.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_cache_seek(struct nffs_cache_inode *cache_inode, uint32_t seek_offset,
                struct nffs_cache_block **out_cache_block)
{
    struct nffs_cache_block *cache_block;
    struct nffs_hash_entry *last_cached_entry;
    struct nffs_hash_entry *block_entry;
    struct nffs_hash_entry *pred_entry;
    struct nffs_block block;
    uint32_t cache_start;
    uint32_t cache_end;
    uint32_t block_start;
    uint32_t block_end;
    int rc;

    /* Empty files have no blocks that can be cached. */
    if (cache_inode->nci_file_size == 0) {
        return FS_ENOENT;
    }

    nffs_cache_inode_range(cache_inode, &cache_start, &cache_end);
    if (cache_end != 0 && seek_offset < cache_start) {
        /* Seeking prior to cache.  Iterate backwards from cache start. */
        cache_block = TAILQ_FIRST(&cache_inode->nci_block_list);
        block_entry = cache_block->ncb_block.nb_prev;
        block_end = cache_block->ncb_file_offset;
        cache_block = NULL;
    } else if (seek_offset < cache_end) {
        /* Seeking within cache.  Iterate backwards from cache end. */
        cache_block = TAILQ_LAST(&cache_inode->nci_block_list,
                                 nffs_cache_block_list);
        block_entry = cache_block->ncb_block.nb_hash_entry;
        block_end = cache_end;
    } else {
        /* Seeking beyond end of cache.  Iterate backwards from file end.  If
         * sought-after block is adjacent to cache end, its cache entry will
         * get appended to the current cache.  Otherwise, the current cache
         * will be freed and replaced with the single requested block.
         */
        cache_block = NULL;
        block_entry =
            cache_inode->nci_inode.ni_inode_entry->nie_last_block_entry;
        block_end = cache_inode->nci_file_size;
    }

    /* Scan backwards until we find the block containing the seek offest. */
    while (1) {
        if (block_end <= cache_start) {
            /* We are looking before the start of the cache.  Allocate a new
             * cache block and prepend it to the cache.
             */
            assert(cache_block == NULL);
            cache_block = nffs_cache_block_acquire();
            rc = nffs_cache_block_populate(cache_block, block_entry,
                                           block_end);
            if (rc != 0) {
                return rc;
            }

            nffs_cache_insert_block(cache_inode, cache_block, 0);
        }

        /* Calculate the file offset of the start of this block.  This is used
         * to determine if this block contains the sought-after offset.
         */
        if (cache_block != NULL) {
            /* Current block is cached. */
            block_start = cache_block->ncb_file_offset;
            pred_entry = cache_block->ncb_block.nb_prev;
        } else {
            /* We are looking beyond the end of the cache.  Read the data block
             * from flash.
             */
            rc = nffs_block_from_hash_entry(&block, block_entry);
            if (rc != 0) {
                return rc;
            }

            block_start = block_end - block.nb_data_len;
            pred_entry = block.nb_prev;
        }

        if (block_start <= seek_offset) {
            /* This block contains the requested address; iteration is
             * complete.
             */
           if (cache_block == NULL) {
                /* The block isn't cached, so it must come after the cache end.
                 * Append it to the cache if it directly follows.  Otherwise,
                 * erase the current cache and populate it with this single
                 * block.
                 */
                cache_block = nffs_cache_block_acquire();
                cache_block->ncb_block = block;
                cache_block->ncb_file_offset = block_start;

                last_cached_entry = nffs_cache_inode_last_entry(cache_inode);
                if (last_cached_entry != NULL &&
                    last_cached_entry == pred_entry) {

                    nffs_cache_insert_block(cache_inode, cache_block, 1);
                } else {
                    nffs_cache_inode_free_blocks(cache_inode);
                    nffs_cache_insert_block(cache_inode, cache_block, 0);
                }
            }

            if (out_cache_block != NULL) {
                *out_cache_block = cache_block;
            }
            break;
        }

        /* Prepare for next iteration. */
        if (cache_block != NULL) {
            cache_block = TAILQ_PREV(cache_block, nffs_cache_block_list,
                                     ncb_link);
        }
        block_entry = pred_entry;
        block_end = block_start;
    }

    return 0;
}

/**
 * Frees all cached inodes and blocks.
 */
void
nffs_cache_clear(void)
{
    struct nffs_cache_inode *entry;

    while ((entry = TAILQ_FIRST(&nffs_cache_inode_list)) != NULL) {
        TAILQ_REMOVE(&nffs_cache_inode_list, entry, nci_link);
        nffs_cache_inode_free(entry);
    }
}
