/*
 * 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_priv.h"
#include "nffs/nffs.h"
#include "fs/fs_if.h"

struct fs_ops nffs_ops;

static struct nffs_file *
nffs_file_alloc(void)
{
    struct nffs_file *file;

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

    return file;
}

static int
nffs_file_free(struct nffs_file *file)
{
    int rc;

    if (file != NULL) {
        rc = os_memblock_put(&nffs_file_pool, file);
        if (rc != 0) {
            return FS_EOS;
        }
    }

    return 0;
}

/**
 * Creates a new empty file and writes it to the file system.  If a file with
 * the specified path already exists, the behavior is undefined.
 *
 * @param parent                The parent directory to insert the new file in.
 * @param filename              The name of the file to create.
 * @param filename_len          The length of the filename, in characters.
 * @param is_dir                1 if this is a directory; 0 if it is a normal
 *                                  file.
 * @param out_inode_entry       On success, this points to the inode
 *                                  corresponding to the new file.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
nffs_file_new(struct nffs_inode_entry *parent, const char *filename,
              uint8_t filename_len, int is_dir,
              struct nffs_inode_entry **out_inode_entry)
{
    struct nffs_disk_inode disk_inode;
    struct nffs_inode_entry *inode_entry;
    uint32_t offset;
    uint8_t area_idx;
    int rc;

    rc = nffs_inode_entry_reserve(&inode_entry);
    if (rc != 0) {
        goto err;
    }

    rc = nffs_misc_reserve_space(sizeof disk_inode + filename_len,
                                 &area_idx, &offset);
    if (rc != 0) {
        goto err;
    }

    memset(&disk_inode, 0, sizeof disk_inode);
    if (is_dir) {
        disk_inode.ndi_id = nffs_hash_next_dir_id++;
    } else {
        disk_inode.ndi_id = nffs_hash_next_file_id++;
    }
    disk_inode.ndi_seq = 0;
    disk_inode.ndi_lastblock_id = NFFS_ID_NONE;
    if (parent == NULL) {
        disk_inode.ndi_parent_id = NFFS_ID_NONE;
    } else {
        disk_inode.ndi_parent_id = parent->nie_hash_entry.nhe_id;
    }
    disk_inode.ndi_filename_len = filename_len;
    disk_inode.ndi_flags = 0;
    nffs_crc_disk_inode_fill(&disk_inode, filename);

    rc = nffs_inode_write_disk(&disk_inode, filename, area_idx, offset);
    if (rc != 0) {
        goto err;
    }

    inode_entry->nie_hash_entry.nhe_id = disk_inode.ndi_id;
    inode_entry->nie_hash_entry.nhe_flash_loc =
        nffs_flash_loc(area_idx, offset);
    inode_entry->nie_refcnt = 1;
    inode_entry->nie_last_block_entry = NULL;

    if (parent != NULL) {
        rc = nffs_inode_add_child(parent, inode_entry);
        if (rc != 0) {
            goto err;
        }
    } else {
        assert(disk_inode.ndi_id == NFFS_ID_ROOT_DIR);
        nffs_inode_setflags(inode_entry, NFFS_INODE_FLAG_INTREE);
    }

    nffs_hash_insert(&inode_entry->nie_hash_entry);
    *out_inode_entry = inode_entry;

    return 0;

err:
    nffs_inode_entry_free(inode_entry);
    return rc;
}

/**
 * Performs a file open operation.
 *
 * @param out_file          On success, a pointer to the newly-created file
 *                              handle gets written here.
 * @param path              The path of the file to open.
 * @param access_flags      Flags controlling file access; see nffs_open() for
 *                              details.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
nffs_file_open(struct nffs_file **out_file, const char *path,
               uint8_t access_flags)
{
    struct nffs_path_parser parser;
    struct nffs_inode_entry *parent;
    struct nffs_inode_entry *inode;
    struct nffs_file *file;
    int rc;

    file = NULL;

    /* Reject invalid access flag combinations. */
    if (!(access_flags & (FS_ACCESS_READ | FS_ACCESS_WRITE))) {
        rc = FS_EINVAL;
        goto err;
    }
    if (access_flags & (FS_ACCESS_APPEND | FS_ACCESS_TRUNCATE) &&
        !(access_flags & FS_ACCESS_WRITE)) {

        rc = FS_EINVAL;
        goto err;
    }
    if (access_flags & FS_ACCESS_APPEND &&
        access_flags & FS_ACCESS_TRUNCATE) {

        rc = FS_EINVAL;
        goto err;
    }

    file = nffs_file_alloc();
    if (file == NULL) {
        rc = FS_ENOMEM;
        goto err;
    }

    nffs_path_parser_new(&parser, path);
    rc = nffs_path_find(&parser, &inode, &parent);
    if (rc == FS_ENOENT && parser.npp_token_type == NFFS_PATH_TOKEN_LEAF) {
        /* The path is valid, but the file does not exist.  This is an error
         * for read-only opens.
         */
        if (!(access_flags & FS_ACCESS_WRITE)) {
            goto err;
        }

        /* Make sure the parent directory exists. */
        if (parent == NULL) {
            goto err;
        }

        /* Create a new file at the specified path. */
        rc = nffs_file_new(parent, parser.npp_token, parser.npp_token_len, 0,
                           &file->nf_inode_entry);
        if (rc != 0) {
            goto err;
        }
    } else if (rc == 0) {
        /* The file already exists. */

        /* Reject an attempt to open a directory. */
        if (nffs_hash_id_is_dir(inode->nie_hash_entry.nhe_id)) {
            rc = FS_EINVAL;
            goto err;
        }

        if (access_flags & FS_ACCESS_TRUNCATE) {
            /* The user is truncating the file.  Unlink the old file and create
             * a new one in its place.
             */
            nffs_path_unlink(path);
            rc = nffs_file_new(parent, parser.npp_token, parser.npp_token_len,
                               0, &file->nf_inode_entry);
            if (rc != 0) {
                goto err;
            }
        } else {
            /* The user is not truncating the file.  Point the file handle to
             * the existing inode.
             */
            file->nf_inode_entry = inode;
        }
    } else {
        /* Invalid path. */
        goto err;
    }

    if (access_flags & FS_ACCESS_APPEND) {
        rc = nffs_inode_data_len(file->nf_inode_entry, &file->nf_offset);
        if (rc != 0) {
            goto err;
        }
    } else {
        file->nf_offset = 0;
    }
    nffs_inode_inc_refcnt(file->nf_inode_entry);
    file->nf_access_flags = access_flags;
    file->fops = &nffs_ops;

    *out_file = file;

    return 0;

err:
    nffs_file_free(file);
    return rc;
}

/**
 * Positions a file's read and write pointer at the specified offset.  The
 * offset is expressed as the number of bytes from the start of the file (i.e.,
 * seeking to 0 places the pointer at the first byte in the file).
 *
 * @param file              The file to reposition.
 * @param offset            The offset from the start of the file to seek to.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
nffs_file_seek(struct nffs_file *file, uint32_t offset)
{ 
    uint32_t len;
    int rc;

    rc = nffs_inode_data_len(file->nf_inode_entry, &len);
    if (rc != 0) {
        return rc;
    }

    if (offset > len) {
        return FS_EOFFSET;
    }

    file->nf_offset = offset;
    return 0;
}

/**
 * Reads data from the specified file.  If more data is requested than remains
 * in the file, all available data is retrieved.  Note: this type of short read
 * results in a success return code.
 *
 * @param file              The file to read from.
 * @param len               The number of bytes to attempt to read.
 * @param out_data          The destination buffer to read into.
 * @param out_len           On success, the number of bytes actually read gets
 *                              written here.  Pass null if you don't care.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
nffs_file_read(struct nffs_file *file, uint32_t len, void *out_data,
               uint32_t *out_len)
{
    uint32_t bytes_read;
    int rc;

    if (!nffs_misc_ready()) {
        return FS_EUNINIT;
    }

    if (!(file->nf_access_flags & FS_ACCESS_READ)) {
        return FS_EACCESS;
    }

    rc = nffs_inode_read(file->nf_inode_entry, file->nf_offset, len, out_data,
                        &bytes_read);
    if (rc != 0) {
        return rc;
    }

    file->nf_offset += bytes_read;
    if (out_len != NULL) {
        *out_len = bytes_read;
    }

    return 0;
}

/**
 * Closes the specified file and invalidates the file handle.  If the file has
 * already been unlinked, and this is the last open handle to the file, this
 * operation causes the file to be deleted.
 *
 * @param file              The file handle to close.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
nffs_file_close(struct nffs_file *file)
{
    int rc;

    rc = nffs_inode_dec_refcnt(file->nf_inode_entry);
    if (rc != 0) {
        return rc;
    }

    rc = nffs_file_free(file);
    if (rc != 0) {
        return rc;
    }

    return 0;
}
