// Generated by CoffeeScript 1.10.0
var CachedFile, File, W,
  extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  hasProp = {}.hasOwnProperty;

File = require('./');

W = require('when');

CachedFile = (function(superClass) {
  extend(CachedFile, superClass);


  /**
   * The encoding of the file. Used as a default for `File.read` and
   * `File.write`.
   */

  CachedFile.prototype.encoding = void 0;


  /**
   * The content of the file. Can be modified directly and if it is edited
     File.save() will be needed to persist the changes on disk.
   * @type {String}
   */

  CachedFile.prototype.content = '';


  /**
   * The content loaded from the disk (cannot be modified because we need this
     when saving to avoid needing to re-read the file).
   * @type {String}
   * @private
   */

  CachedFile.prototype._savedContent = void 0;


  /**
   * The time at which the file was last loaded. Used to determine if we are
     overwriting new data.
   * @type {Integer}
   * @private
   */

  CachedFile.prototype._loadTime = void 0;


  /**
   * @param {String|null} [options.encoding='utf8']
   */

  function CachedFile(path, options) {
    var ref;
    if (options == null) {
      options = {};
    }
    this.encoding = (ref = options.encoding) != null ? ref : 'utf8';
    CachedFile.__super__.constructor.call(this, path, options);
  }


  /**
   * Read from the file
   * @param {String} [options.flag='r']
   * @return {Promise}
   */

  CachedFile.prototype.read = function(options) {
    if (options == null) {
      options = {};
    }
    options.encoding = this.encoding;
    return CachedFile.__super__.read.call(this, options);
  };


  /**
   * Write `data` to the file
   * @param {String|Buffer} data
   * @param {Number} [options.mode=438] default is 0666 in Octal
   * @param {String} [options.flag='w']
   * @return {Promise}
   */

  CachedFile.prototype.write = function(data, options) {
    if (options == null) {
      options = {};
    }
    options.encoding = this.encoding;
    return CachedFile.__super__.write.call(this, data, options);
  };


  /**
   * Append `data` to the file
   * @param {String|Buffer} data
   * @param {Number} [options.mode=438] default is 0666 in Octal
   * @param {String} [options.flag='w']
   * @return {Promise}
   */

  CachedFile.prototype.append = function(data, options) {
    if (options == null) {
      options = {};
    }
    options.encoding = this.encoding;
    return CachedFile.__super__.append.call(this, data, options);
  };


  /**
   * Check the file mod-time to see if the file has been edited since the last
     time we loaded it. Also, make sure that we've loaded the file.
   * @return {Promise}
   */

  CachedFile.prototype._isFileNewerOnDisk = function() {
    return this.stat().then((function(_this) {
      return function(stat) {
        return (_this._loadTime != null) && stat.mtime > _this._loadTime;
      };
    })(this));
  };


  /**
   * Write CachedFile.content to the disk, using optimizations like appending
     rather than overwriting entirely.
   * @param {Boolean} [overwrite=true] Even if the file has been modified since
     the last load, overwrite it.
   * @return {Promise}
   */

  CachedFile.prototype.save = function(overwrite) {
    var promise;
    if (overwrite == null) {
      overwrite = true;
    }
    promise = W.resolve();
    if (!overwrite) {
      promise.then(this._isFileNewerOnDisk).then(function(isFileNewerOnDisk) {
        if (isFileNewerOnDisk) {
          throw new Error('File has been modified since last load');
        }
      });
    }
    return promise.then((function(_this) {
      return function() {
        if ((_this._savedContent != null) && _this.content.slice(0, _this._savedContent.length) === _this._savedContent) {
          if (!overwrite) {
            return _this.append(_this.content.slice(_this._savedContent.length));
          } else {
            return _this._isFileNewerOnDisk().then(function(isFileNewerOnDisk) {
              if (isFileNewerOnDisk) {
                return _this.write(_this.content);
              } else {
                return _this.append(_this.content.slice(_this._savedContent.length));
              }
            });
          }
        } else {
          return _this.write(_this.content);
        }
      };
    })(this)).then((function(_this) {
      return function() {
        _this._loadTime = Date.now();
        _this._savedContent = _this.content;
      };
    })(this));
  };


  /**
   * Load the file from the disk, overwriting anything in CachedFile.content
   * @return {Promise}
   */

  CachedFile.prototype.load = function() {
    return this.read().then((function(_this) {
      return function(data) {
        var _loadTime;
        _loadTime = Date.now();
        return _this._savedContent = _this.content = data;
      };
    })(this));
  };

  return CachedFile;

})(File);

module.exports = CachedFile;
