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

#include "cborattr/cborattr.h"
#include "mgmt/mgmt.h"

#include "img_mgmt/image.h"
#include "img_mgmt/img_mgmt.h"
#include "img_mgmt/img_mgmt_impl.h"
#include "img_mgmt_priv.h"
#include "img_mgmt/img_mgmt_config.h"

static mgmt_handler_fn img_mgmt_upload;
static mgmt_handler_fn img_mgmt_erase;
static img_mgmt_upload_fn *img_mgmt_upload_cb;
static void *img_mgmt_upload_arg;

const img_mgmt_dfu_callbacks_t *img_mgmt_dfu_callbacks_fn;

struct img_mgmt_state g_img_mgmt_state;

static const struct mgmt_handler img_mgmt_handlers[] = {
    [IMG_MGMT_ID_STATE] = {
        .mh_read = img_mgmt_state_read,
        .mh_write = img_mgmt_state_write,
    },
    [IMG_MGMT_ID_UPLOAD] = {
        .mh_read = NULL,
        .mh_write = img_mgmt_upload
    },
    [IMG_MGMT_ID_ERASE] = {
        .mh_read = NULL,
        .mh_write = img_mgmt_erase
    },
};

#define IMG_MGMT_HANDLER_CNT \
    sizeof(img_mgmt_handlers) / sizeof(img_mgmt_handlers[0])

static struct mgmt_group img_mgmt_group = {
    .mg_handlers = (struct mgmt_handler *)img_mgmt_handlers,
    .mg_handlers_count = IMG_MGMT_HANDLER_CNT,
    .mg_group_id = MGMT_GROUP_ID_IMAGE,
};

#if IMG_MGMT_VERBOSE_ERR
const char *img_mgmt_err_str_app_reject = "app reject";
const char *img_mgmt_err_str_hdr_malformed = "header malformed";
const char *img_mgmt_err_str_magic_mismatch = "magic mismatch";
const char *img_mgmt_err_str_no_slot = "no slot";
const char *img_mgmt_err_str_flash_open_failed = "fa open fail";
const char *img_mgmt_err_str_flash_erase_failed = "fa erase fail";
const char *img_mgmt_err_str_flash_write_failed = "fa write fail";
const char *img_mgmt_err_str_downgrade = "downgrade";
const char *img_mgmt_err_str_image_bad_flash_addr = "img addr mismatch";
#endif

/**
 * Finds the TLVs in the specified image slot, if any.
 */
static int
img_mgmt_find_tlvs(int slot, size_t *start_off, size_t *end_off,
                   uint16_t magic)
{
    struct image_tlv_info tlv_info;
    int rc;

    rc = img_mgmt_impl_read(slot, *start_off, &tlv_info, sizeof tlv_info);
    if (rc != 0) {
        /* Read error. */
        return MGMT_ERR_EUNKNOWN;
    }

    if (tlv_info.it_magic != magic) {
        /* No TLVs. */
        return MGMT_ERR_ENOENT;
    }

    *start_off += sizeof tlv_info;
    *end_off = *start_off + tlv_info.it_tlv_tot;

    return 0;
}

/*
 * Reads the version and build hash from the specified image slot.
 */
int
img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash,
                   uint32_t *flags)
{

#if IMG_MGMT_DUMMY_HDR
    uint8_t dummy_hash[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};

    if (!hash && !ver && !flags) {
        return 0;
    }

    if (hash) {
        memcpy(hash, dummy_hash, IMG_MGMT_HASH_LEN);
    }

    if (ver) {
        memset(ver, 0xff, sizeof *ver);
    }

    if (flags) {
        *flags = 0;
    }

    return 0;
#endif

    struct image_header hdr;
    struct image_tlv tlv;
    size_t data_off;
    size_t data_end;
    bool hash_found;
    uint8_t erased_val;
    uint32_t erased_val_32;
    int rc;

    rc = img_mgmt_impl_erased_val(image_slot, &erased_val);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    rc = img_mgmt_impl_read(image_slot, 0, &hdr, sizeof hdr);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    if (ver != NULL) {
        memset(ver, erased_val, sizeof(*ver));
    }
    erased_val_32 = ERASED_VAL_32(erased_val);
    if (hdr.ih_magic == IMAGE_MAGIC) {
        if (ver != NULL) {
            memcpy(ver, &hdr.ih_ver, sizeof(*ver));
        }
    } else if (hdr.ih_magic == erased_val_32) {
        return MGMT_ERR_ENOENT;
    } else {
        return MGMT_ERR_EUNKNOWN;
    }

    if (flags != NULL) {
        *flags = hdr.ih_flags;
    }

    /* Read the image's TLVs. We first try to find the protected TLVs, if the protected
     * TLV does not exist, we try to find non-protected TLV which also contains the hash
     * TLV. All images are required to have a hash TLV.  If the hash is missing, the image
     * is considered invalid.
     */
    data_off = hdr.ih_hdr_size + hdr.ih_img_size;

    rc = img_mgmt_find_tlvs(image_slot, &data_off, &data_end, IMAGE_TLV_PROT_INFO_MAGIC);
    if (!rc) {
        /* The data offset should start after the header bytes after the end of the protected TLV,
         * if one exists.
         */
        data_off = data_end - sizeof(struct image_tlv_info);
    }

    rc = img_mgmt_find_tlvs(image_slot, &data_off, &data_end, IMAGE_TLV_INFO_MAGIC);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    hash_found = false;
    while (data_off + sizeof tlv <= data_end) {
        rc = img_mgmt_impl_read(image_slot, data_off, &tlv, sizeof tlv);
        if (rc != 0) {
            return MGMT_ERR_EUNKNOWN;
        }
        if (tlv.it_type == 0xff && tlv.it_len == 0xffff) {
            return MGMT_ERR_EUNKNOWN;
        }
        if (tlv.it_type != IMAGE_TLV_SHA256 || tlv.it_len != IMAGE_HASH_LEN) {
            /* Non-hash TLV.  Skip it. */
            data_off += sizeof tlv + tlv.it_len;
            continue;
        }

        if (hash_found) {
            /* More than one hash. */
            return MGMT_ERR_EUNKNOWN;
        }
        hash_found = true;

        data_off += sizeof tlv;
        if (hash != NULL) {
            if (data_off + IMAGE_HASH_LEN > data_end) {
                return MGMT_ERR_EUNKNOWN;
            }
            rc = img_mgmt_impl_read(image_slot, data_off, hash,
                                    IMAGE_HASH_LEN);
            if (rc != 0) {
                return MGMT_ERR_EUNKNOWN;
            }
        }
    }

    if (!hash_found) {
        return MGMT_ERR_EUNKNOWN;
    }

    return 0;
}

/*
 * Finds image given version number. Returns the slot number image is in,
 * or -1 if not found.
 */
int
img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash)
{
    int i;
    struct image_version ver;

    for (i = 0; i < 2; i++) {
        if (img_mgmt_read_info(i, &ver, hash, NULL) != 0) {
            continue;
        }
        if (!memcmp(find, &ver, sizeof(ver))) {
            return i;
        }
    }
    return -1;
}

/*
 * Finds image given hash of the image. Returns the slot number image is in,
 * or -1 if not found.
 */
int
img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver)
{
    int i;
    uint8_t hash[IMAGE_HASH_LEN];

    for (i = 0; i < 2; i++) {
        if (img_mgmt_read_info(i, ver, hash, NULL) != 0) {
            continue;
        }
        if (!memcmp(hash, find, IMAGE_HASH_LEN)) {
            return i;
        }
    }
    return -1;
}

#if IMG_MGMT_VERBOSE_ERR
int
img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn)
{
    /*
     * This is an error response so returning a different error when failed to
     * encode other error probably does not make much sense - just ignore errors
     * here.
     */
    cbor_encode_text_stringz(&ctxt->encoder, "rsn");
    cbor_encode_text_stringz(&ctxt->encoder, rsn);
    return rc;
}
#endif

/**
 * Command handler: image erase
 */
static int
img_mgmt_erase(struct mgmt_ctxt *ctxt)
{
    struct image_version ver;
    CborError err;
    int rc;

    /*
     * First check if image info is valid.
     * This check is done incase the flash area has a corrupted image.
     */
    rc = img_mgmt_read_info(1, &ver, NULL, NULL);

    if (rc == 0) {
        /* Image info is valid. */
        if (img_mgmt_slot_in_use(1)) {
            /* No free slot. */
            return MGMT_ERR_EBADSTATE;
        }
    }
    
    rc = img_mgmt_impl_erase_slot();

    err = 0;
    err |= cbor_encode_text_stringz(&ctxt->encoder, "rc");
    err |= cbor_encode_int(&ctxt->encoder, rc);

    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;
}

static int
img_mgmt_upload_good_rsp(struct mgmt_ctxt *ctxt)
{
    CborError err = CborNoError;

    err |= cbor_encode_text_stringz(&ctxt->encoder, "rc");
    err |= cbor_encode_int(&ctxt->encoder, MGMT_ERR_EOK);
    err |= cbor_encode_text_stringz(&ctxt->encoder, "off");
    err |= cbor_encode_int(&ctxt->encoder, g_img_mgmt_state.off);

    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;
}

/**
 * Logs an upload request if necessary.
 *
 * @param is_first              Whether the request includes the first chunk of
 *                                  the image.
 * @param is_last               Whether the request includes the last chunk of
 *                                  the image.
 * @param status                The result of processing the upload request
 *                                  (MGMT_ERR code).
 *
 * @return                      0 on success; nonzero on failure.
 */
static int
img_mgmt_upload_log(bool is_first, bool is_last, int status)
{
    uint8_t hash[IMAGE_HASH_LEN];
    const uint8_t *hashp;
    int rc;

    if (is_first) {
        return img_mgmt_impl_log_upload_start(status);
    }

    if (is_last || status != 0) {
        /* Log the image hash if we know it. */
        rc = img_mgmt_read_info(1, NULL, hash, NULL);
        if (rc != 0) {
            hashp = NULL;
        } else {
            hashp = hash;
        }

        return img_mgmt_impl_log_upload_done(status, hashp);
    }

    /* Nothing to log. */
    return 0;
}

/**
 * Command handler: image upload
 */
static int
img_mgmt_upload(struct mgmt_ctxt *ctxt)
{
    struct mgmt_evt_op_cmd_status_arg cmd_status_arg;
    struct img_mgmt_upload_req req = {
        .off = -1,
        .size = -1,
        .data_len = 0,
        .data_sha_len = 0,
        .upgrade = false,
    };

    const struct cbor_attr_t off_attr[] = {
        [0] = {
            .attribute = "data",
            .type = CborAttrByteStringType,
            .addr.bytestring.data = req.img_data,
            .addr.bytestring.len = &req.data_len,
            .len = sizeof(req.img_data)
        },
        [1] = {
            .attribute = "len",
            .type = CborAttrUnsignedIntegerType,
            .addr.uinteger = &req.size,
            .nodefault = true
        },
        [2] = {
            .attribute = "off",
            .type = CborAttrUnsignedIntegerType,
            .addr.uinteger = &req.off,
            .nodefault = true
        },
        [3] = {
            .attribute = "sha",
            .type = CborAttrByteStringType,
            .addr.bytestring.data = req.data_sha,
            .addr.bytestring.len = &req.data_sha_len,
            .len = sizeof(req.data_sha)
        },
        [4] = {
            .attribute = "upgrade",
            .type = CborAttrBooleanType,
            .addr.boolean = &req.upgrade,
            .dflt.boolean = false,
        },
        [5] = { 0 },
    };
    int rc;
    const char *errstr = NULL;
    struct img_mgmt_upload_action action;
    bool last = false;

    rc = cbor_read_object(&ctxt->it, off_attr);
    if (rc != 0) {
        return MGMT_ERR_EINVAL;
    }

    /* Determine what actions to take as a result of this request. */
    rc = img_mgmt_impl_upload_inspect(&req, &action, &errstr);
    if (rc != 0) {
        img_mgmt_dfu_stopped();
        return rc;
    }

    if (!action.proceed) {
        /* Request specifies incorrect offset.  Respond with a success code and
         * the correct offset.
         */
        return img_mgmt_upload_good_rsp(ctxt);
    }

    /* Request is valid.  Give the application a chance to reject this upload
     * request.
     */
    if (img_mgmt_upload_cb != NULL) {
        rc = img_mgmt_upload_cb(req.off, action.size, img_mgmt_upload_arg);
        if (rc != 0) {
            errstr = img_mgmt_err_str_app_reject;
            goto end;
        }
    }

    /* Remember flash area ID and image size for subsequent upload requests. */
    g_img_mgmt_state.area_id = action.area_id;
    g_img_mgmt_state.size = action.size;

    if (req.off == 0) {
        /*
         * New upload.
         */
        g_img_mgmt_state.off = 0;

        img_mgmt_dfu_started();
        cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_START;

        /*
         * We accept SHA trimmed to any length by client since it's up to client
         * to make sure provided data are good enough to avoid collisions when
         * resuming upload.
         */
        g_img_mgmt_state.data_sha_len = req.data_sha_len;
        memcpy(g_img_mgmt_state.data_sha, req.data_sha, req.data_sha_len);
        memset(&g_img_mgmt_state.data_sha[req.data_sha_len], 0,
               IMG_MGMT_DATA_SHA_LEN - req.data_sha_len);

#if IMG_MGMT_LAZY_ERASE
        /* setup for lazy sector by sector erase */
        g_img_mgmt_state.sector_id = -1;
        g_img_mgmt_state.sector_end = 0;
#else
        /* erase the entire req.size all at once */
        if (action.erase) {
            rc = img_mgmt_impl_erase_image_data(0, req.size);
            if (rc != 0) {
                rc = MGMT_ERR_EUNKNOWN;
                errstr = img_mgmt_err_str_flash_erase_failed;
                goto end;
            }
        }
#endif
    }

    /* Write the image data to flash. */
    if (req.data_len != 0) {
#if IMG_MGMT_LAZY_ERASE
        /* erase as we cross sector boundaries */
        if (img_mgmt_impl_erase_if_needed(req.off, action.write_bytes) != 0) {
            rc = MGMT_ERR_EUNKNOWN;
            errstr = img_mgmt_err_str_flash_erase_failed;
            goto end;
        }
#endif
        /* If this is the last chunk */
        if (g_img_mgmt_state.off + req.data_len == g_img_mgmt_state.size) {
            last = true;
        }

        rc = img_mgmt_impl_write_image_data(req.off, req.img_data, action.write_bytes, last);
        if (rc != 0) {
            rc = MGMT_ERR_EUNKNOWN;
            errstr = img_mgmt_err_str_flash_write_failed;
            goto end;
        } else {
            g_img_mgmt_state.off += action.write_bytes;
            if (g_img_mgmt_state.off == g_img_mgmt_state.size) {
                /* Done */
                img_mgmt_dfu_pending();
                cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING;
                g_img_mgmt_state.area_id = -1;
            }
        }
    }

end:

    img_mgmt_upload_log(req.off == 0, g_img_mgmt_state.off == g_img_mgmt_state.size, rc);
    mgmt_evt(MGMT_EVT_OP_CMD_STATUS, MGMT_GROUP_ID_IMAGE, IMG_MGMT_ID_UPLOAD,
             &cmd_status_arg);

    if (rc != 0) {
        img_mgmt_dfu_stopped();
        return img_mgmt_error_rsp(ctxt, rc, errstr);
    }

    return img_mgmt_upload_good_rsp(ctxt);
}

void
img_mgmt_dfu_stopped(void)
{
    if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_stopped_cb) {
        img_mgmt_dfu_callbacks_fn->dfu_stopped_cb();
    }
}

void
img_mgmt_dfu_started(void)
{
    if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_started_cb) {
        img_mgmt_dfu_callbacks_fn->dfu_started_cb();
    }
}

void
img_mgmt_dfu_pending(void)
{
    if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_pending_cb) {
        img_mgmt_dfu_callbacks_fn->dfu_pending_cb();
    }
}

void
img_mgmt_dfu_confirmed(void)
{
    if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb) {
        img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb();
    }
}

void
img_mgmt_set_upload_cb(img_mgmt_upload_fn *cb, void *arg)
{
    img_mgmt_upload_cb = cb;
    img_mgmt_upload_arg = arg;
}

void
img_mgmt_register_callbacks(const img_mgmt_dfu_callbacks_t *cb_struct)
{
    img_mgmt_dfu_callbacks_fn = cb_struct;
}


int
img_mgmt_my_version(struct image_version *ver)
{
    return img_mgmt_read_info(IMG_MGMT_BOOT_CURR_SLOT, ver, NULL, NULL);
}

void
img_mgmt_register_group(void)
{
    mgmt_register_group(&img_mgmt_group);
}
