'use strict';

/*
 * Memory abstraction layer
 *
 * The methods build the interface to the memory.
 * Currently only for path
 * The idea is to cache paths as roomPosition in a global object.
 * Store paths from my rooms in a compressed form in memory.
 */

Room.prototype.getMemoryPaths = function() {
  this.memory.routing = this.memory.routing || {};
  cache.rooms[this.name] = cache.rooms[this.name] || {};
  cache.rooms[this.name].routing = cache.rooms[this.name].routing || {};
  let memoryKeys = Object.keys(this.memory.routing).sort();
  let cacheKeys = Object.keys(cache.rooms[this.name].routing).sort();
  let diff = _.difference(memoryKeys, cacheKeys);
  for (let item of diff) {
    this.log(`getPaths ${item} missing in cache`);
    cache.rooms[this.name].routing[item] = {
      path: Room.stringToPath(this.memory.routing[item].path),
      created: this.memory.routing[item].created,
      fixed: this.memory.routing[item].fixed,
      name: this.memory.routing[item].name
    };
  }
  return cache.rooms[this.name].routing;
};

Room.prototype.getMemoryPath = function(name) {
  this.memory.routing = this.memory.routing || {};
  cache.rooms[this.name] = cache.rooms[this.name] || {};
  cache.rooms[this.name].routing = cache.rooms[this.name].routing || {};

  let isValid = function(path) {
    return path.fixed || path.created > Game.time - config.path.refresh;
  };

  if (cache.rooms[this.name].routing[name] && isValid(cache.rooms[this.name].routing[name])) {
    return cache.rooms[this.name].routing[name].path;
  }

  if (this.memory.routing[name] && isValid(this.memory.routing[name])) {
    this.log(`getPath ${name} missing in cache`);
    cache.rooms[this.name].routing[name] = {
      path: Room.stringToPath(this.memory.routing[name].path),
      created: this.memory.routing[name].created,
      fixed: this.memory.routing[name].fixed,
      name: this.memory.routing[name].name
    };
    return cache.rooms[this.name].routing[name].path;
  }
  return false;
};

Room.prototype.deleteMemoryPaths = function() {
  this.memory.routing = this.memory.routing || {};
  cache.rooms[this.name] = cache.rooms[this.name] || {};
  cache.rooms[this.name].routing = cache.rooms[this.name].routing || {};
  delete cache.rooms[this.name].routing;
  delete this.memory.routing;
};

Room.prototype.deleteMemoryPath = function(name) {
  this.memory.routing = this.memory.routing || {};
  cache.rooms[this.name] = cache.rooms[this.name] || {};
  delete cache.rooms[this.name].routing[name];
  delete this.memory.routing[name];
};

Room.prototype.setMemoryPath = function(name, path, fixed) {
  this.memory.routing = this.memory.routing || {};
  cache.rooms[this.name] = cache.rooms[this.name] || {};
  cache.rooms[this.name].routing = cache.rooms[this.name].routing || {};
  let data = {
    path: path,
    created: Game.time,
    fixed: fixed,
    name: name
  };
  cache.rooms[this.name].routing[name] = data;
  if (fixed) {
    let memoryData = {
      path: Room.pathToString(path),
      created: Game.time,
      fixed: fixed,
      name: name
    };
    this.memory.routing[name] = memoryData;
  }
};

@@ -1665,110 +1665,286 @@
     
-cache.rooms%5Bthis.name%5D.routing%5Bname%5D = %7B%0A      path: Room.stringToPath(this.memory.routing%5Bname%5D.path)
+let path;%0A    try %7B%0A      path = Room.stringToPath(this.memory.routing%5Bname%5D.path);%0A    %7D catch (e) %7B%0A      path = this.memory.routing%5Bname%5D.path;%0A      this.memory.routing%5Bname%5D.path = Room.pathToString(path);%0A    %7D%0A    cache.rooms%5Bthis.name%5D.routing%5Bname%5D = %7B%0A      path: path
 ,%0A  

Fix transition to room cache