var path = require( 'path' );
var fs = require( 'fs' );
var utils = require( './utils' );
var del = require( './del' );
var writeJSON = utils.writeJSON;

var cache = {
  /**
   * Load a cache identified by the given Id. If the element does not exists, then initialize an empty
   * cache storage. If specified `cacheDir` will be used as the directory to persist the data to. If omitted
   * then the cache module directory `./cache` will be used instead
   *
   * @method load
   * @param docId {String} the id of the cache, would also be used as the name of the file cache
   * @param [cacheDir] {String} directory for the cache entry
   */
  load: function ( docId, cacheDir ) {
    var me = this;

    me._visited = { };
    me._persisted = { };
    me._pathToFile = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId );

    if ( fs.existsSync( me._pathToFile ) ) {
      me._persisted = utils.tryParse( me._pathToFile, { } );
    }
  },

  /**
   * Load the cache from the provided file
   * @method loadFile
   * @param  {String} pathToFile the path to the file containing the info for the cache
   */
  loadFile: function ( pathToFile ) {
    var me = this;
    var dir = path.dirname( pathToFile );
    var fName = path.basename( pathToFile );

    me.load( fName, dir );
  },

  /**
   * Returns the entire persisted object
   * @method all
   * @returns {*}
   */
  all: function () {
    return this._persisted;
  },

  keys: function () {
    return Object.keys( this._persisted );
  },
  /**
   * sets a key to a given value
   * @method setKey
   * @param key {string} the key to set
   * @param value {object} the value of the key. Could be any object that can be serialized with JSON.stringify
   */
  setKey: function ( key, value ) {
    this._visited[ key ] = true;
    this._persisted[ key ] = value;
  },
  /**
   * remove a given key from the cache
   * @method removeKey
   * @param key {String} the key to remove from the object
   */
  removeKey: function ( key ) {
    delete this._visited[ key ]; // esfmt-ignore-line
    delete this._persisted[ key ]; // esfmt-ignore-line
  },
  /**
   * Return the value of the provided key
   * @method getKey
   * @param key {String} the name of the key to retrieve
   * @returns {*} the value from the key
   */
  getKey: function ( key ) {
    this._visited[ key ] = true;
    return this._persisted[ key ];
  },

  /**
   * Remove keys that were not accessed/set since the
   * last time the `prune` method was called.
   * @method _prune
   * @private
   */
  _prune: function () {
    var me = this;
    var obj = { };

    var keys = Object.keys( me._visited );

    // no keys visited for either get or set value
    if ( keys.length === 0 ) {
      return;
    }

    keys.forEach( function ( key ) {
      obj[ key ] = me._persisted[ key ];
    } );

    me._visited = { };
    me._persisted = obj;
  },

  /**
   * Save the state of the cache identified by the docId to disk
   * as a JSON structure
   * @param [noPrune=false] {Boolean} whether to remove from cache the non visited files
   * @method save
   */
  save: function ( noPrune ) {
    var me = this;

    (!noPrune) && me._prune();
    writeJSON( me._pathToFile, me._persisted );
  },

  /**
   * remove the file where the cache is persisted
   * @method removeCacheFile
   * @return {Boolean} true or false if the file was successfully deleted
   */
  removeCacheFile: function () {
    return del( this._pathToFile );
  },
  /**
   * Destroy the file cache and cache content.
   * @method destroy
   */
  destroy: function () {
    var me = this;
    me._visited = { };
    me._persisted = { };

    me.removeCacheFile();
  }
};

module.exports = {
  /**
   * Alias for create. Should be considered depreacted. Will be removed in next releases
   *
   * @method load
   * @param docId {String} the id of the cache, would also be used as the name of the file cache
   * @param [cacheDir] {String} directory for the cache entry
   * @returns {cache} cache instance
   */
  load: function ( docId, cacheDir ) {
    return this.create( docId, cacheDir );
  },

  /**
  * Load a cache identified by the given Id. If the element does not exists, then initialize an empty
  * cache storage.
  *
  * @method create
  * @param docId {String} the id of the cache, would also be used as the name of the file cache
  * @param [cacheDir] {String} directory for the cache entry
  * @returns {cache} cache instance
  */
  create: function ( docId, cacheDir ) {
    var obj = Object.create( cache );
    obj.load( docId, cacheDir );
    return obj;
  },

  createFromFile: function ( filePath ) {
    var obj = Object.create( cache );
    obj.loadFile( filePath );
    return obj;
  },
  /**
   * Clear the cache identified by the given id. Caches stored in a different cache directory can be deleted directly
   *
   * @method clearCache
   * @param docId {String} the id of the cache, would also be used as the name of the file cache
   * @param cacheDir {String} the directory where the cache file was written
   * @returns {Boolean} true if the cache folder was deleted. False otherwise
   */
  clearCacheById: function ( docId, cacheDir ) {
    var filePath = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId );
    return del( filePath );
  },
  /**
   * Remove all cache stored in the cache directory
   * @method clearAll
   * @returns {Boolean} true if the cache folder was deleted. False otherwise
   */
  clearAll: function ( cacheDir ) {
    var filePath = cacheDir ? path.resolve( cacheDir ) : path.resolve( __dirname, './.cache/' );
    return del( filePath );
  }
};
