(function() {
  var AtomIoClient, fs, glob, path, request;

  fs = require('fs-plus');

  path = require('path');

  glob = null;

  request = null;

  module.exports = AtomIoClient = (function() {
    function AtomIoClient(packageManager, baseURL) {
      this.packageManager = packageManager;
      this.baseURL = baseURL;
      if (this.baseURL == null) {
        this.baseURL = 'https://atom.io/api/';
      }
      this.expiry = 1000 * 60 * 60 * 12;
      this.createAvatarCache();
      this.expireAvatarCache();
    }

    AtomIoClient.prototype.avatar = function(login, callback) {
      return this.cachedAvatar(login, (function(_this) {
        return function(err, cached) {
          var stale;
          if (cached) {
            stale = Date.now() - parseInt(cached.split('-').pop()) > _this.expiry;
          }
          if (cached && (!stale || !_this.online())) {
            return callback(null, cached);
          } else {
            return _this.fetchAndCacheAvatar(login, callback);
          }
        };
      })(this));
    };

    AtomIoClient.prototype["package"] = function(name, callback) {
      var packagePath;
      packagePath = "packages/" + name;
      return this.fetchFromCache(packagePath, {}, (function(_this) {
        return function(err, data) {
          if (data) {
            return callback(null, data);
          } else {
            return _this.request(packagePath, callback);
          }
        };
      })(this));
    };

    AtomIoClient.prototype.featuredPackages = function(callback) {
      return this.fetchFromCache('packages/featured', {}, (function(_this) {
        return function(err, data) {
          if (data) {
            return callback(null, data);
          } else {
            return _this.getFeatured(false, callback);
          }
        };
      })(this));
    };

    AtomIoClient.prototype.featuredThemes = function(callback) {
      return this.fetchFromCache('themes/featured', {}, (function(_this) {
        return function(err, data) {
          if (data) {
            return callback(null, data);
          } else {
            return _this.getFeatured(true, callback);
          }
        };
      })(this));
    };

    AtomIoClient.prototype.getFeatured = function(loadThemes, callback) {
      return this.packageManager.getFeatured(loadThemes).then((function(_this) {
        return function(packages) {
          var cached, key;
          key = loadThemes ? 'themes/featured' : 'packages/featured';
          cached = {
            data: packages,
            createdOn: Date.now()
          };
          localStorage.setItem(_this.cacheKeyForPath(key), JSON.stringify(cached));
          return callback(null, packages);
        };
      })(this))["catch"]((function(_this) {
        return function(error) {
          return callback(error, null);
        };
      })(this));
    };

    AtomIoClient.prototype.request = function(path, callback) {
      if (request == null) {
        request = require('request');
      }
      return request("" + this.baseURL + path, (function(_this) {
        return function(err, res, body) {
          var cached, data, error;
          try {
            data = JSON.parse(body);
          } catch (_error) {
            error = _error;
            return callback(error);
          }
          delete data.versions;
          cached = {
            data: data,
            createdOn: Date.now()
          };
          localStorage.setItem(_this.cacheKeyForPath(path), JSON.stringify(cached));
          return callback(err, cached.data);
        };
      })(this));
    };

    AtomIoClient.prototype.cacheKeyForPath = function(path) {
      return "settings-view:" + path;
    };

    AtomIoClient.prototype.online = function() {
      return navigator.onLine;
    };

    AtomIoClient.prototype.fetchFromCache = function(packagePath, options, callback) {
      var cached;
      if (!callback) {
        callback = options;
        options = {};
      }
      if (!options.force) {
        options.force = !this.online();
      }
      cached = localStorage.getItem(this.cacheKeyForPath(packagePath));
      cached = cached ? JSON.parse(cached) : void 0;
      if ((cached != null) && (!this.online() || options.force || (Date.now() - cached.createdOn < this.expiry))) {
        if (cached == null) {
          cached = {
            data: {}
          };
        }
        return callback(null, cached.data);
      } else if ((cached == null) && !this.online()) {
        return callback(null, {});
      } else {
        return callback(null, null);
      }
    };

    AtomIoClient.prototype.createAvatarCache = function() {
      return fs.makeTree(this.getCachePath());
    };

    AtomIoClient.prototype.avatarPath = function(login) {
      return path.join(this.getCachePath(), "" + login + "-" + (Date.now()));
    };

    AtomIoClient.prototype.cachedAvatar = function(login, callback) {
      if (glob == null) {
        glob = require('glob');
      }
      return glob(this.avatarGlob(login), (function(_this) {
        return function(err, files) {
          var createdOn, filename, imagePath, _i, _len, _ref;
          files.sort().reverse();
          for (_i = 0, _len = files.length; _i < _len; _i++) {
            imagePath = files[_i];
            filename = path.basename(imagePath);
            _ref = filename.split('-'), createdOn = _ref[_ref.length - 1];
            if (Date.now() - parseInt(createdOn) < _this.expiry) {
              return callback(null, imagePath);
            }
          }
          return callback(null, null);
        };
      })(this));
    };

    AtomIoClient.prototype.avatarGlob = function(login) {
      return path.join(this.getCachePath(), "" + login + "-*");
    };

    AtomIoClient.prototype.fetchAndCacheAvatar = function(login, callback) {
      var imagePath, readStream, writeStream;
      if (this.online()) {
        imagePath = this.avatarPath(login);
        writeStream = fs.createWriteStream(imagePath);
        writeStream.on('finish', function() {
          return callback(null, imagePath);
        });
        writeStream.on('error', function(error) {
          return callback(error);
        });
        if (request == null) {
          request = require('request');
        }
        readStream = request("https://github.com/" + login + ".png");
        readStream.on('error', function(error) {
          return callback(error);
        });
        return readStream.pipe(writeStream);
      } else {
        return callback(null, null);
      }
    };

    AtomIoClient.prototype.expireAvatarCache = function() {
      var deleteAvatar;
      deleteAvatar = (function(_this) {
        return function(child) {
          var avatarPath;
          avatarPath = path.join(_this.getCachePath(), child);
          return fs.unlink(avatarPath, function(error) {
            if (error && error.code !== 'ENOENT') {
              return console.warn("Error deleting avatar (" + error.code + "): " + avatarPath);
            }
          });
        };
      })(this);
      return fs.readdir(this.getCachePath(), (function(_this) {
        return function(error, _files) {
          var children, filename, files, keep, key, parts, stamp, _i, _len, _results;
          if (_files == null) {
            _files = [];
          }
          files = {};
          for (_i = 0, _len = _files.length; _i < _len; _i++) {
            filename = _files[_i];
            parts = filename.split('-');
            stamp = parts.pop();
            key = parts.join('-');
            if (files[key] == null) {
              files[key] = [];
            }
            files[key].push("" + key + "-" + stamp);
          }
          _results = [];
          for (key in files) {
            children = files[key];
            children.sort();
            keep = children.pop();
            _results.push(children.forEach(deleteAvatar));
          }
          return _results;
        };
      })(this));
    };

    AtomIoClient.prototype.getCachePath = function() {
      return this.cachePath != null ? this.cachePath : this.cachePath = path.join(require('remote').require('app').getDataPath(), 'Cache', 'settings-view');
    };

    return AtomIoClient;

  })();

}).call(this);
