/*
 * 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 <fs/fs.h>
#include <mgmt/mgmt.h>
#include <fs_mgmt/fs_mgmt_impl.h>

int
fs_mgmt_impl_filelen(const char *path, size_t *out_len)
{
    struct fs_dirent dirent;
    int rc;

    rc = fs_stat(path, &dirent);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    if (dirent.type != FS_DIR_ENTRY_FILE) {
        return MGMT_ERR_EUNKNOWN;
    }

    *out_len = dirent.size;

    return 0;
}

int
fs_mgmt_impl_read(const char *path, size_t offset, size_t len,
                  void *out_data, size_t *out_len)
{
    struct fs_file_t file;
    ssize_t bytes_read;
    int rc;

    rc = fs_open(&file, path);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    rc = fs_seek(&file, offset, FS_SEEK_SET);
    if (rc != 0) {
        goto done;
    }

    bytes_read = fs_read(&file, out_data, len);
    if (bytes_read < 0) {
        goto done;
    }

    *out_len = bytes_read;

done:
    fs_close(&file);

    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    } else {
        return 0;
    }
}

static int
zephyr_fs_mgmt_truncate(const char *path)
{
    size_t len;
    int rc;

    /* Attempt to get the length of the file at the specified path.  This is a
     * quick way to determine if there is already a file there.
     */
    rc = fs_mgmt_impl_filelen(path, &len);
    if (rc == 0) {
        /* There is already a file with the specified path.  Unlink it to
         * simulate a truncate operation.
         *
         * XXX: This isn't perfect - if the file is currently open, the unlink
         * operation won't actually delete the file.  Consequently, the file
         * will get partially overwritten rather than truncated.  The NFFS port
         * doesn't support the truncate operation, so this is an imperfect
         * workaround.
         */
        rc = fs_unlink(path);
        if (rc != 0) {
            return MGMT_ERR_EUNKNOWN;
        }
    }

    return 0;
}

int
fs_mgmt_impl_write(const char *path, size_t offset, const void *data,
                   size_t len)
{
    struct fs_file_t file;
    int rc;
 
    /* Truncate the file before writing the first chunk.  This is done to
     * properly handle an overwrite of an existing file.
     *
     */
    if (offset == 0) {
        rc = zephyr_fs_mgmt_truncate(path);
        if (rc != 0) {
            return rc;
        }
    }

    rc = fs_open(&file, path);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    rc = fs_seek(&file, offset, FS_SEEK_SET);
    if (rc != 0) {
        goto done;
    }

    rc = fs_write(&file, data, len);
    if (rc < 0) {
        goto done;
    }

    rc = 0;

done:
    fs_close(&file);

    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    } else {
        return 0;
    }
}
