/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright (c) 2015 Adobe Systems Incorporated. All rights reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, bitwise: true, node:true */
/*global require: true, $: true, exports: true, csInterface: true*/

(function () {
    "use strict";
    //this simple wrapper just forces us to have an "interface" with a basic DI mode 
    var defaultInterface = require("./MemoryInterface.js"),
        _ = require("underscore");

    //This is less than ideal, it means we have to store the keys twice.
    //Once inside the cache and another time in whatever storage mechanism we use.
    //it does however let us forget about implementation details and have the interfaceimpl worry about it.
    var LRUCache = require("../LRUCache"),
        LRUKEY = "LRU";

    var UserSettings = function (settingsInterface) {
        this.settingsInterface = settingsInterface || defaultInterface;
        this._LRUCache = new LRUCache(100);
    };

    //this unfortunatly has to load every time due to the shared nature of the file.
    //we could be smarter about it, but its easy to just load it all again.
    UserSettings.prototype._LoadLRUFromStorage = function() {
        var LRUObject = this.settingsInterface.get(LRUKEY);
        //if we are anything but an object here just ovewrite it
        LRUObject = _.isObject(LRUObject) ? LRUObject : {};
        Object.keys(LRUObject).forEach(function(key) {
            if(this._LRUCache.set(key, LRUObject[key])) {
                console.warn("too many keys loaded from storage, this is a problem");
            }
        }, this);
    };

    UserSettings.prototype.set = function(settings) {
        if(!settings) return;
        if(typeof settings !== "object" && arguments[1]) {
            var key = settings;
            settings = {};
            settings[key] = arguments[1];
        }
        settings = settings || {};
        this.settingsInterface.set(settings);
    };

    //for simplicity sake lets just match the LRU cache api
    //I am starting to become less and less sure of this api.
    //due to reasons outlined below
    UserSettings.prototype.setCachedValue = function(key, value) {
        this._LoadLRUFromStorage();
        this._LRUCache.set(key, value);
        //this will be fine for anyone using extend.
        //i guess its a fair pre condition that set overwrites any value - that includes for complex values
        //  var key = keys[i]; if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
        var obj = {};
        obj[LRUKEY] =  this._LRUCache.serialize();
        this.settingsInterface.set(obj);
    };

    //having one get interface is a bit confusing.
    //as it means you can never set the same key twice.
    //having the user to have to know if the key is a LRU value or a persisted value is also not great.
    //we could split this into two objects?
    //not the biggest deal now, but something i need to think about best to approach.
    UserSettings.prototype.get = function(key) {
        this._LoadLRUFromStorage();
        return this._LRUCache.get(key) || this.settingsInterface.get(key);
    };

    module.exports = UserSettings;
})();