'use strict';

var bind = function (fn, me) { return function () { return fn.apply(me, arguments); }; }
var autoUpdater = null;
var events = require('events');
var util = require('util');
var path = require('path');
var json = require("./package.json")

// States
var IdleState = 'idle';
var CheckingState = 'checking';
var DownladingState = 'downloading';
var UpdateAvailableState = 'update-available';
var NoUpdateAvailableState = 'no-update-available';
var UnsupportedState = 'unsupported';
var ErrorState = 'error';


module.exports = (function () {

  function UpdateManager(version) {
    this.version = version;
    this.onUpdateError = bind(this.onUpdateError, this);
    this.onUpdateNotAvailable = bind(this.onUpdateNotAvailable, this);
    this.state = IdleState;
    if (process.platform === 'win32') {
      // FIXME: we don't support win32 yet
      this.feedUrl = null;
    } else {
      // TODO: set our iconPath
      this.iconPath = path.resolve(__dirname, './macicon.png');
      this.feedUrl = `${json.pubuim.apiUrl}/services/release?version=${this.version}&platform=${process.platform}`;
    }
    process.nextTick((function (_this) {
      return function () {
        return _this.setupAutoUpdater();
      };
    })(this));
  }

  util.inherits(UpdateManager, events.EventEmitter);

  UpdateManager.prototype.setupAutoUpdater = function () {
    if (process.platform === 'win32') {
      // FIXME: we don't support win32 yet
      autoUpdater = null; //require('./auto-updater-win32');
      return;
    } else {
      autoUpdater = require('auto-updater');
    }
    autoUpdater.on('error', (function (_this) {
      return function (event, message) {
        _this.setState(ErrorState);
        return console.error("Error Downloading Update: " + message);
      };
    })(this));
    autoUpdater.setFeedUrl(this.feedUrl);
    autoUpdater.on('checking-for-update', (function (_this) {
      return function () {
        return _this.setState(CheckingState);
      };
    })(this));
    autoUpdater.on('update-not-available', (function (_this) {
      return function () {
        return _this.setState(NoUpdateAvailableState);
      };
    })(this));
    autoUpdater.on('update-available', (function (_this) {
      return function () {
        return _this.setState(DownladingState);
      };
    })(this));
    autoUpdater.on('update-downloaded', (function (_this) {
      return function (event, releaseNotes, releaseVersion, releaseDate, updateUrl) {
        _this.releaseInfo = {
          releaseVersion: releaseVersion,
          releaseNotes: releaseNotes,
          releaseDate: releaseDate,
          updateUrl: updateUrl
        };
        _this.setState(UpdateAvailableState);
        // return _this.emitUpdateAvailableEvent.apply(_this, _this.getWindows());
        return _this.emitUpdateAvailableEvent();
      };
    })(this));

    if (!/\w{7}/.test(this.version)) {
      this.scheduleUpdateCheck();
    }
    switch (process.platform) {
      case 'win32':
        // FIXME: we don't support win32 yet
        // if (autoUpdater.supportsUpdates()) {
        return this.setState(UnsupportedState);
      // }
      case 'linux':
        return this.setState(UnsupportedState);
    }
  };

  UpdateManager.prototype.emitUpdateAvailableEvent = function () {
    if (this.releaseInfo == null) {
      return;
    }
    return this.emit('update-downloaded', this.releaseInfo);
  };

  UpdateManager.prototype.setState = function (state) {
    if (this.state === state) {
      return;
    }
    this.state = state;
    return this.emit('state-changed', this.state);
  };

  UpdateManager.prototype.getState = function () {
    return this.state;
  };

  UpdateManager.prototype.scheduleUpdateCheck = function () {
    var checkForUpdates, fourHours;
    checkForUpdates = (function (_this) {
      return function () {
        return _this.check({
          hidePopups: true
        });
      };
    })(this);
    fourHours = 1000 * 60 * 60 * 4;
    setInterval(checkForUpdates, fourHours);
    return checkForUpdates();
  };

  UpdateManager.prototype.check = function (arg) {
    var hidePopups;
    hidePopups = (arg != null ? arg : {}).hidePopups;

    if (autoUpdater == null) {
      return;
    }

    if (!hidePopups) {
      autoUpdater.once('update-not-available', this.onUpdateNotAvailable);
      autoUpdater.once('error', this.onUpdateError);
    }
    return autoUpdater.checkForUpdates();
  };

  UpdateManager.prototype.install = function () {
    return autoUpdater.quitAndInstall();
  };

  UpdateManager.prototype.onUpdateNotAvailable = function () {
    var dialog;
    autoUpdater.removeListener('error', this.onUpdateError);
    dialog = require('dialog');
    return dialog.showMessageBox({
      type: 'info',
      buttons: ['OK'],
      icon: this.iconPath,
      message: '没有可用的更新',
      title: '没有可用的更新',
      detail: "版本 " + this.version + " 是当前最新版本。"
    });
  };

  UpdateManager.prototype.onUpdateError = function (event, message) {
    var dialog;
    autoUpdater.removeListener('update-not-available', this.onUpdateNotAvailable);
    dialog = require('dialog');
    return dialog.showMessageBox({
      type: 'warning',
      buttons: ['OK'],
      icon: this.iconPath,
      message: '更新时发生了错误。',
      title: '更新失败',
      detail: message
    });
  };
  return UpdateManager;

})();
