/*
 $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.
 */
#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 (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) {
                checksum = inv_checksum(data, hd->size);
                if (checksum == hd->checksum) {
                    ds.load[entry](data);
                } else {
                    return INV_ERROR_CALIBRATION_LOAD;
                }
            }
        }
        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 (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;
}

/**
 * @}
 */
