/*
 $License:
    Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
    See included License.txt for License information.
 $
 */

/**
 *   @defgroup  Storage_Manager storage_manager
 *   @brief     Motion Library - Stores Data for functions.
 *
 *
 *   @{
 *       @file storage_manager.c
 *       @brief Load and Store Manager.
 */
#undef MPL_LOG_NDEBUG
#define MPL_LOG_NDEBUG 0 /* Use 0 to turn on MPL_LOGV output */
#undef MPL_LOG_TAG
#define MPL_LOG_TAG "MLLITE"

#include <string.h>

#include "storage_manager.h"
#include "log.h"
#include "ml_math_func.h"
#include "mlmath.h"

/* Must be changed if the format of storage changes */
#define DEFAULT_KEY 29681

typedef inv_error_t (*load_func_t)(const unsigned char *data);
typedef inv_error_t (*save_func_t)(unsigned char *data);
/** Max number of entites that can be stored */
#define NUM_STORAGE_BOXES 20

struct data_header_t {
    long size;
    uint32_t checksum;
    unsigned int key;
};

struct data_storage_t {
    int num; /**< Number of differnt save entities */
    size_t total_size; /**< Size in bytes to store non volatile data */
    load_func_t load[NUM_STORAGE_BOXES]; /**< Callback to load data */
    save_func_t save[NUM_STORAGE_BOXES]; /**< Callback to save data */
    struct data_header_t hd[NUM_STORAGE_BOXES]; /**< Header info for each entity */
};
static struct data_storage_t ds;

/** Should be called once before using any of the storage methods. Typically
* called first by inv_init_mpl().*/
void inv_init_storage_manager()
{
    memset(&ds, 0, sizeof(ds));
    ds.total_size = sizeof(struct data_header_t);
}

/** Used to register your mechanism to load and store non-volative data. This should typical be
* called during the enable function for your feature.
* @param[in] load_func function pointer you will use to receive data that was stored for you.
* @param[in] save_func function pointer you will use to save any data you want saved to
*            non-volatile memory between runs.
* @param[in] size The size in bytes of the amount of data you want loaded and saved.
* @param[in] key The key associated with your data type should be unique across MPL.
*                    The key should change when your type of data for storage changes.
* @return Returns INV_SUCCESS if successful or an error code if not.
*/
inv_error_t inv_register_load_store(inv_error_t (*load_func)(const unsigned char *data),
                                    inv_error_t (*save_func)(unsigned char *data), size_t size, unsigned int key)
{
    int kk;
    // Check if this has been registered already
    for (kk=0; kk<ds.num; ++kk) {
        if (key == ds.hd[kk].key) {
            return INV_ERROR_INVALID_PARAMETER;
        }
    }
    // Make sure there is room
    if (ds.num >= NUM_STORAGE_BOXES) {
        return INV_ERROR_INVALID_PARAMETER;
    }
    // Add to list
    ds.hd[ds.num].key = key;
    ds.hd[ds.num].size = size;
    ds.load[ds.num] = load_func;
    ds.save[ds.num] = save_func;
    ds.total_size += size + sizeof(struct data_header_t);
    ds.num++;

    return INV_SUCCESS;
}

/** Returns the memory size needed to perform a store
* @param[out] size Size in bytes of memory needed to store.
* @return Returns INV_SUCCESS if successful or an error code if not.
*/
inv_error_t inv_get_mpl_state_size(size_t *size)
{
    *size = ds.total_size;
    return INV_SUCCESS;
}

/** @internal
 * Finds key in ds.hd[] array and returns location
 * @return location where key exists in array, -1 if not found.
 */
static int inv_find_entry(unsigned int key)
{
    int kk;
    for (kk=0; kk<ds.num; ++kk) {
        if (key == ds.hd[kk].key) {
            return kk;
        }
    }
    return -1;
}

/** This function takes a block of data that has been saved in non-volatile memory and pushes
* to the proper locations. Multiple error checks are performed on the data.
* @param[in] data Data that was saved to be loaded up by MPL
* @param[in] length Length of data vector in bytes
* @return Returns INV_SUCCESS if successful or an error code if not.
*/
inv_error_t inv_load_mpl_states(const unsigned char *data, size_t length)
{
    struct data_header_t *hd;
    int entry;
    uint32_t checksum;
    long len;

    len = length; // Important so we get negative numbers
    if (data == NULL || len == 0)
        return INV_SUCCESS;
    if (len < sizeof(struct data_header_t))
        return INV_ERROR_CALIBRATION_LOAD;  // No data
    hd = (struct data_header_t *)data;
    if (hd->key != DEFAULT_KEY)
        return INV_ERROR_CALIBRATION_LOAD;  // Key changed or data corruption
    len = MIN(hd->size, len);
    len = hd->size;
    len -= sizeof(struct data_header_t);
    data += sizeof(struct data_header_t);
    checksum = inv_checksum(data, len);
    if (checksum != hd->checksum)
        return INV_ERROR_CALIBRATION_LOAD;  // Data corruption

    while (len > (long)sizeof(struct data_header_t)) {
        hd = (struct data_header_t *)data;
        entry = inv_find_entry(hd->key);
        data += sizeof(struct data_header_t);
        len -= sizeof(struct data_header_t);
        if (entry >= 0 && len >= hd->size) {
            if (hd->size != ds.hd[entry].size)
                return INV_ERROR_CALIBRATION_LEN;
            checksum = inv_checksum(data, hd->size);
            if (checksum != hd->checksum)
                return INV_ERROR_CALIBRATION_LOAD;
            ds.load[entry](data);
        }
        len -= hd->size;
        if (len >= 0)
            data = data + hd->size;
    }

    return INV_SUCCESS;
}

/** This function fills up a block of memory to be stored in non-volatile memory.
* @param[out] data Place to store data, size of sz, must be at least size
*                  returned by inv_get_mpl_state_size()
* @param[in] sz Size of data.
* @return Returns INV_SUCCESS if successful or an error code if not.
*/
inv_error_t inv_save_mpl_states(unsigned char *data, size_t sz)
{
    unsigned char *cur;
    int kk;
    struct data_header_t *hd;

    if (data == NULL || sz == 0)
        return INV_ERROR_CALIBRATION_LOAD;
    if (sz >= ds.total_size) {
        cur = data + sizeof(struct data_header_t);
        for (kk = 0; kk < ds.num; ++kk) {
            hd = (struct data_header_t *)cur;
            cur += sizeof(struct data_header_t);
            ds.save[kk](cur);
            hd->checksum = inv_checksum(cur, ds.hd[kk].size);
            hd->size = ds.hd[kk].size;
            hd->key = ds.hd[kk].key;
            cur += ds.hd[kk].size;
        }
    } else {
        return INV_ERROR_CALIBRATION_LOAD;
    }

    hd = (struct data_header_t *)data;
    hd->checksum = inv_checksum(data + sizeof(struct data_header_t),
                                ds.total_size - sizeof(struct data_header_t));
    hd->key = DEFAULT_KEY;
    hd->size = ds.total_size;

    return INV_SUCCESS;
}

/**
 * @}
 */
