"use strict";
/*
 * Storage conventions
 *      All data are saved with keys of the following format to keep things ordered: dml.moduleName.key
 */

App.module("DataModule.Storage", function(Storage, App, Backbone, Marionette, $, _, Logger) {
    // Prevent auto start
    //Storage.startWithParent = false;

    // Define private variables
    var logger = null;

    /**
     * Initialization checker
     */
    var assertModuleIsInitialized = function() {
        if (!logger) {
            throw "Storage has not been initialized";
        }
    };

    /**
     * Module initializer
     *
     */
    Storage.addInitializer(function(){
        logger = Logger.get("DataModule.Storage");
        // logger.setLevel(Logger.DEBUG);

        logger.debug("Begin init");
        logger.debug("End init");
    });

    /**
     * @memberOf App.Storage
     *
     * @returns {Boolean} true when success, false when failure (e.g. local storage is full or disabled)
     */
    Storage.setStrCache = function(module, key, value) {
        assertModuleIsInitialized();
        var moduleName = _.isObject(module) ? module.moduleName : "";
        if (!moduleName) {
            moduleName = "";
        }
        if (value === undefined) {
            localStorage && localStorage.removeItem("dml." + moduleName + "." + key);
            return true;
        } else if (_.isString(value)) {
            try {
                localStorage && localStorage.setItem("dml." + moduleName + "." + key, value);
                logger.info("Set string cache", moduleName, key, value);
                return true;
            } catch (e) {
                var maxOutputLength = 100;
                logger.error("Set string cache failed:", moduleName, "→", key, "=", value.slice(0, maxOutputLength) + (value.length > maxOutputLength ? "..." : ""));
                //logger.error("Set string cache failed:", moduleName, "→", key, "=", value);
                return false;
            }
        } else {
            throw _.str.sprintf("Storage.setStrCache only accepts string for value, %s given: ", typeof value, value)
        }
    };

    /**
     * @memberOf App.Storage
     *
     * @returns {String|undefined}
     */
    Storage.getStrCache = function(module, key) {
        assertModuleIsInitialized();
        var moduleName = _.isObject(module) ? module.moduleName : "";
        if (!moduleName) {
            moduleName = "";
        }
        var value = localStorage ? localStorage.getItem("dml." + moduleName + "." + key) : null;
        if (value === null) {
            value = undefined;
        }
        logger.info("Get string cache", module, key, value);
        return value;
    };

    /**
     * @memberOf App.Storage
     *
     * @returns {Boolean} true when success, false when failure (e.g. local storage is full or disabled)
     */
    Storage.setObjCache = function(module, key, value) {
        if (!(_.isUndefined(value) || _.isNull(value) || (_.isObject(value) && !_.isFunction(value)))) {
            throw _.str.sprintf("Storage.setObjCache can only acccept object, got %s", value);
        }
        var str = JSON.stringify(value);
        return Storage.setStrCache(module, key, str);
    };

    /**
     * @memberOf App.Storage
     *
     * @returns {Object|undefined}
     */
    Storage.getObjCache = function(module, key) {
        assertModuleIsInitialized();
        var value = localStorage ? localStorage.getItem("dml." + module.moduleName + "." + key) : null;
        if (value === null) {
            return undefined;
        }
        if (value === "null") {
            return null;
        }
        try {
            var value = JSON.parse(value);
            return value;
        } catch (e) {
            return null;
        }
    };

}, Logger);
