/*
 * 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 "os/mynewt.h"

#if MYNEWT_VAL(FS_NMGR)

#include <limits.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

#include "bootutil/image.h"
#include "fs/fs.h"
#include "cborattr/cborattr.h"
#include "bsp/bsp.h"
#include "mgmt/mgmt.h"

#include "fs/fs.h"
#include "fs_priv.h"

static struct {
    struct {
        uint32_t off;
        uint32_t size;
        const struct flash_area *fa;
        struct fs_file *file;
    } upload;
} fs_nmgr_state;

static int fs_nmgr_file_download(struct mgmt_cbuf *cb);
static int fs_nmgr_file_upload(struct mgmt_cbuf *cb);

static const struct mgmt_handler fs_nmgr_handlers[] = {
    [FS_NMGR_ID_FILE] = {
        .mh_read = fs_nmgr_file_download,
        .mh_write = fs_nmgr_file_upload
    },
};

#define FS_NMGR_HANDLER_CNT                                                \
    sizeof(fs_nmgr_handlers) / sizeof(fs_nmgr_handlers[0])

static struct mgmt_group fs_nmgr_group = {
    .mg_handlers = fs_nmgr_handlers,
    .mg_handlers_count = FS_NMGR_HANDLER_CNT,
    .mg_group_id = MGMT_GROUP_ID_FS,
};

static int
fs_nmgr_file_download(struct mgmt_cbuf *cb)
{
    long long unsigned int off = UINT_MAX;
    char tmp_str[FS_NMGR_MAX_NAME + 1];
    uint8_t img_data[MYNEWT_VAL(FS_UPLOAD_MAX_CHUNK_SIZE)];
    const struct cbor_attr_t dload_attr[3] = {
        [0] = {
            .attribute = "off",
            .type = CborAttrUnsignedIntegerType,
            .addr.uinteger = &off
        },
        [1] = {
            .attribute = "name",
            .type = CborAttrTextStringType,
            .addr.string = tmp_str,
            .len = sizeof(tmp_str)
        },
        [2] = { 0 },
    };
    int rc;
    uint32_t out_len;
    struct fs_file *file;
    CborError g_err = CborNoError;

    rc = cbor_read_object(&cb->it, dload_attr);
    if (rc || off == UINT_MAX) {
        return MGMT_ERR_EINVAL;
    }

    rc = fs_open(tmp_str, FS_ACCESS_READ, &file);
    if (rc || !file) {
        return MGMT_ERR_ENOMEM;
    }

    rc = fs_seek(file, off);
    if (rc) {
        rc = MGMT_ERR_EUNKNOWN;
        goto err_close;
    }
    rc = fs_read(file, 32, img_data, &out_len);
    if (rc) {
        rc = MGMT_ERR_EUNKNOWN;
        goto err_close;
    }

    g_err |= cbor_encode_text_stringz(&cb->encoder, "off");
    g_err |= cbor_encode_uint(&cb->encoder, off);

    g_err |= cbor_encode_text_stringz(&cb->encoder, "data");
    g_err |= cbor_encode_byte_string(&cb->encoder, img_data, out_len);

    g_err |= cbor_encode_text_stringz(&cb->encoder, "rc");
    g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK);
    if (off == 0) {
        rc = fs_filelen(file, &out_len);
        g_err |= cbor_encode_text_stringz(&cb->encoder, "len");
        g_err |= cbor_encode_uint(&cb->encoder, out_len);
    }

    fs_close(file);
    if (g_err) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;

err_close:
    fs_close(file);
    return rc;
}

static int
fs_nmgr_file_upload(struct mgmt_cbuf *cb)
{
    uint8_t img_data[MYNEWT_VAL(FS_UPLOAD_MAX_CHUNK_SIZE)];
    char file_name[FS_NMGR_MAX_NAME + 1];
    size_t img_len;
    long long unsigned int off = UINT_MAX;
    long long unsigned int size = UINT_MAX;
    const struct cbor_attr_t off_attr[5] = {
        [0] = {
            .attribute = "off",
            .type = CborAttrUnsignedIntegerType,
            .addr.uinteger = &off,
            .nodefault = true
        },
        [1] = {
            .attribute = "data",
            .type = CborAttrByteStringType,
            .addr.bytestring.data = img_data,
            .addr.bytestring.len = &img_len,
            .len = sizeof(img_data)
        },
        [2] = {
            .attribute = "len",
            .type = CborAttrUnsignedIntegerType,
            .addr.uinteger = &size,
            .nodefault = true
        },
        [3] = {
            .attribute = "name",
            .type = CborAttrTextStringType,
            .addr.string = file_name,
            .len = sizeof(file_name)
        },
        [4] = { 0 },
    };
    CborError g_err = CborNoError;
    int rc;

    rc = cbor_read_object(&cb->it, off_attr);
    if (rc || off == UINT_MAX) {
        return MGMT_ERR_EINVAL;
    }

    if (off == 0) {
        /*
         * New upload.
         */
        fs_nmgr_state.upload.off = 0;
        fs_nmgr_state.upload.size = size;

        if (!strlen(file_name)) {
            return MGMT_ERR_EINVAL;
        }
        if (fs_nmgr_state.upload.file) {
            fs_close(fs_nmgr_state.upload.file);
            fs_nmgr_state.upload.file = NULL;
        }
        rc = fs_open(file_name, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE,
          &fs_nmgr_state.upload.file);
        if (rc) {
            return MGMT_ERR_EINVAL;
        }
    } else if (off != fs_nmgr_state.upload.off) {
        /*
         * Invalid offset. Drop the data, and respond with the offset we're
         * expecting data for.
         */
        goto out;
    }

    if (!fs_nmgr_state.upload.file) {
        return MGMT_ERR_EINVAL;
    }
    if (img_len) {
        rc = fs_write(fs_nmgr_state.upload.file, img_data, img_len);
        if (rc) {
            rc = MGMT_ERR_EINVAL;
            goto err_close;
        }
        fs_nmgr_state.upload.off += img_len;
        if (fs_nmgr_state.upload.size == fs_nmgr_state.upload.off) {
            /* Done */
            fs_close(fs_nmgr_state.upload.file);
            fs_nmgr_state.upload.file = NULL;
        }
    }

out:
    g_err |= cbor_encode_text_stringz(&cb->encoder, "rc");
    g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK);
    g_err |= cbor_encode_text_stringz(&cb->encoder, "off");
    g_err |= cbor_encode_uint(&cb->encoder, fs_nmgr_state.upload.off);
    if (g_err) {
        return MGMT_ERR_ENOMEM;
    }
    return 0;

err_close:
    fs_close(fs_nmgr_state.upload.file);
    fs_nmgr_state.upload.file = NULL;
    return rc;
}

int
fs_nmgr_init(void)
{
    int rc;

    rc = mgmt_group_register(&fs_nmgr_group);
    return rc;
}
#endif
