'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _electron = require('electron');

var _divider = require('./divider');

var _divider2 = _interopRequireDefault(_divider);

var _reactBootstrap = require('react-bootstrap');

var _reactRedux = require('react-redux');

var _lodash = require('lodash');

var _glob = require('glob');

var _utils = require('./utils');

var _update = require('views/services/update');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

const { ROOT, POI_VERSION, CONST, i18n, config } = window;
const __ = i18n.setting.__.bind(i18n.setting);
const { changeChannel, updater } = process.platform !== 'linux' ? _electron.remote.require('./lib/updater') : {};

config.on('config.set', (path, value) => {
  if (path === 'poi.betaChannel' && process.platform !== 'linux') {
    changeChannel(value ? "beta" : "latest");
  }
});

const serverList = ["https://poi.io/fcd/", "https://raw.githubusercontent.com/poooi/poi/master/assets/data/fcd/", "http://7xj6zx.com1.z0.glb.clouddn.com/"];

const fetchHeader = new Headers();
fetchHeader.set("Cache-Control", "max-age=0");

const fetchFromRemote = (() => {
  var _ref = _asyncToGenerator(function* (url, cacheMode = "default") {
    const res = yield fetch(url, { method: "GET", cache: cacheMode, headers: fetchHeader }).catch(function (e) {
      return e;
    });
    if (res.status === 200) {
      try {
        return yield res.json();
      } catch (e) {
        return;
      }
    }
  });

  return function fetchFromRemote(_x) {
    return _ref.apply(this, arguments);
  };
})();

class DownloadProgress extends _react.Component {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.state = {
      bytesPerSecond: 0,
      percent: 0,
      total: 0,
      transferred: 0
    }, this.updateProgress = progress => {
      this.setState(progress);
    }, _temp;
  }

  componentDidMount() {
    if (!this.updateProgressDebounced) {
      this.updateProgressDebounced = (0, _lodash.throttle)(this.updateProgress, 1500);
    }
    if (process.platform === 'win32') {
      updater.on('download-progress', progress => this.updateProgressDebounced(progress));
    }
  }
  render() {
    return this.state.percent > 0 && process.platform === 'win32' && _react2.default.createElement(
      'h5',
      { className: 'update-progress' },
      _react2.default.createElement(_reactBootstrap.ProgressBar, { bsStyle: 'success',
        now: this.state.percent }),
      _react2.default.createElement(
        'span',
        null,
        `${Math.round(this.state.bytesPerSecond / 1024)} KB/s, ${Math.round(this.state.transferred / 1048576)} / ${Math.round(this.state.total / 1048576)} MB`
      )
    );
  }
}

class AppMetrics extends _react.PureComponent {
  constructor(props) {
    super(props);

    this.collect = () => {
      const metrics = this.getAppMetrics();

      const total = {};['workingSetSize', 'peakWorkingSetSize'].map(prop => total[prop] = (0, _lodash.round)((0, _lodash.sumBy)(metrics, metric => metric.memory[prop]) / 1000, 2));

      total.percentCPUUsage = (0, _lodash.round)((0, _lodash.sumBy)(metrics, metric => metric.cpu.percentCPUUsage), 2);

      this.setState({
        metrics: (0, _lodash.sortBy)(JSON.parse(JSON.stringify(metrics)), 'pid'),
        total
      });
    };

    this.handleClick = () => {
      const { active } = this.state;
      if (active) {
        clearInterval(this.cycle);
      } else {
        this.collect();
        this.cycle = setInterval(this.collect.bind(this), 5 * 1000);
      }

      this.setState({
        active: !active
      });
    };

    this.getAppMetrics = _electron.remote.require('electron').app.getAppMetrics;

    this.state = {
      metrics: [],
      total: {},
      active: false
    };
  }

  componentWillUnmount() {
    if (this.cycle) {
      clearInterval(this.cycle);
    }
  }

  render() {
    const { metrics, active, total } = this.state;
    return _react2.default.createElement(
      'div',
      null,
      _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          _reactBootstrap.Button,
          { onClick: this.handleClick, bsStyle: active ? 'success' : 'default' },
          active ? _react2.default.createElement(
            'span',
            null,
            __('Monitor on')
          ) : _react2.default.createElement(
            'span',
            null,
            __('Monitor off')
          )
        )
      ),
      active && _react2.default.createElement(
        'div',
        { className: 'metric-table' },
        _react2.default.createElement(
          'div',
          { className: 'metric-row metric-haeder' },
          _react2.default.createElement(
            'span',
            null,
            'PID'
          ),
          ['type', 'working/MB', 'peak/MB', 'private/MB', 'shared/MB', 'CPU/%', 'wakeup'].map(str => _react2.default.createElement(
            'span',
            { key: str, title: str },
            str
          ))
        ),
        metrics.map(metric => _react2.default.createElement(
          'div',
          { className: 'metric-row', key: metric.pid },
          _react2.default.createElement(
            'span',
            null,
            metric.pid
          ),
          _react2.default.createElement(
            'span',
            { title: metric.type },
            metric.type
          ),
          ['workingSetSize', 'peakWorkingSetSize', 'privateBytes', 'sharedBytes'].map(prop => _react2.default.createElement(
            'span',
            { key: prop },
            (0, _lodash.round)((metric.memory || [])[prop] / 1000, 2)
          )),
          ['percentCPUUsage', 'idleWakeupsPerSecond'].map(prop => _react2.default.createElement(
            'span',
            { key: prop },
            (0, _lodash.round)((metric.cpu || [])[prop], 1)
          ))
        )),
        _react2.default.createElement(
          'div',
          { className: 'metric-row metric-total' },
          _react2.default.createElement(
            'span',
            null,
            __('TOTAL')
          ),
          _react2.default.createElement('span', null),
          _react2.default.createElement(
            'span',
            null,
            total.workingSetSize
          ),
          _react2.default.createElement(
            'span',
            null,
            total.peakWorkingSetSize
          ),
          _react2.default.createElement('span', null),
          _react2.default.createElement('span', null),
          _react2.default.createElement(
            'span',
            null,
            total.percentCPUUsage
          ),
          _react2.default.createElement('span', null)
        )
      )
    );
  }
}

const initState = {};

const Others = (0, _reactRedux.connect)(state => ({
  version: state.fcd.version || initState
}))(class others extends _react.Component {
  constructor(...args) {
    var _temp2, _this;

    return _temp2 = _this = super(...args), this.updateData = (cacheMode = 'default') => _asyncToGenerator(function* () {
      // Update from local
      const localFileList = (0, _glob.sync)(`${ROOT}/assets/data/fcd/*`);
      for (const file of localFileList) {
        if (!file.includes('meta.json')) {
          const data = require(file);
          const version = (0, _lodash.get)(data, 'meta.version');
          const name = (0, _lodash.get)(data, 'meta.name');
          if (name && version) {
            const localVersion = (0, _lodash.get)(_this.props.version, name, '1970/01/01/01');
            if (version > localVersion) {
              _this.props.dispatch({
                type: '@@updateFCD',
                value: data
              });
            }
          }
        }
      }
      // Update from server
      let flag;
      for (const server of serverList) {
        flag = true;
        const fileList = yield fetchFromRemote(`${server}meta.json`, cacheMode);
        if (fileList) {
          for (const file of fileList) {
            const localVersion = (0, _lodash.get)(_this.props.version, file.name, '1970/01/01/01');
            if (file.version > localVersion) {
              // eslint-disable-next-line no-console
              console.log(`Updating ${file.name}: current ${localVersion}, remote ${file.version}, mode ${cacheMode}`);
              const data = yield fetchFromRemote(`${server}${file.name}.json`, cacheMode);
              if (data) {
                _this.props.dispatch({
                  type: '@@updateFCD',
                  value: data
                });
              } else {
                flag = false;
              }
            } else {
              // eslint-disable-next-line no-console
              console.log(`No newer version of ${file.name}: current ${localVersion}, remote ${file.version}, mode ${cacheMode}`);
            }
          }
        } else {
          flag = false;
        }
        if (flag) {
          // eslint-disable-next-line no-console
          console.log(`Update fcd from ${server} successfully in mode ${cacheMode}.`);
          break;
        } else {
          console.warn(`Update fcd from ${server} failed in mode ${cacheMode}.`);
        }
      }
    }), _temp2;
  }

  componentDidMount() {
    this.updateData()();
  }
  render() {
    const fcds = Object.keys(this.props.version || {}).map(key => [key, this.props.version[key]]);
    return _react2.default.createElement(
      'div',
      { id: 'poi-others' },
      _react2.default.createElement(
        _reactBootstrap.Grid,
        null,
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 12 },
          _react2.default.createElement('img', { src: `file://${ROOT}/assets/img/logo.png`, style: { width: '100%' } })
        )
      ),
      _react2.default.createElement(
        _reactBootstrap.Grid,
        null,
        _react2.default.createElement(
          _reactBootstrap.Row,
          null,
          _react2.default.createElement(
            _reactBootstrap.Col,
            { xs: 6 },
            _react2.default.createElement(_divider2.default, { text: `${__("Current version")}: ${POI_VERSION}` })
          ),
          _react2.default.createElement(
            _reactBootstrap.Col,
            { xs: 6 },
            _react2.default.createElement(DownloadProgress, null)
          )
        )
      ),
      _react2.default.createElement(
        _reactBootstrap.Grid,
        null,
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 6 },
          _react2.default.createElement(
            _reactBootstrap.Button,
            { onClick: _update.checkUpdate },
            __("Check Update")
          )
        ),
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 6 },
          _react2.default.createElement(_utils.CheckboxLabelConfig, {
            label: __('Check update of beta version'),
            configName: 'poi.betaChannel',
            defaultVal: false })
        ),
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 12 },
          _react2.default.createElement(
            'p',
            null,
            __("poi-description %s", process.versions.electron)
          ),
          window.language === "zh-CN" || window.language === "zh-TW" ? _react2.default.createElement(
            'div',
            null,
            _react2.default.createElement(
              'p',
              null,
              '\u5FAE\u535A: ',
              _react2.default.createElement(
                'a',
                { href: 'http://weibo.com/letspoi' },
                '  \u4ECA\u5929 poi \u51FA\u65B0\u7248\u672C\u4E86\u5417 '
              )
            ),
            _react2.default.createElement(
              'p',
              null,
              '\u5F00\u53D1\u8BA8\u8BBA\u4E0E\u610F\u89C1\u4EA4\u6D41\u7FA4: 378320628 '
            )
          ) : null,
          _react2.default.createElement(
            'p',
            null,
            __("Database"),
            ':',
            _react2.default.createElement(
              'a',
              { href: 'http://db.kcwiki.moe' },
              ' http://db.kcwiki.moe '
            )
          ),
          _react2.default.createElement(
            'p',
            null,
            __("Wiki"),
            ': ',
            _react2.default.createElement(
              'a',
              { href: 'https://github.com/poooi/poi/wiki' },
              ' https://github.com/poooi/poi/wiki '
            )
          ),
          _react2.default.createElement(
            'p',
            null,
            'GitHub\uFF1A',
            _react2.default.createElement(
              'a',
              { href: 'https://github.com/poooi/poi' },
              ' https://github.com/poooi/poi '
            )
          )
        )
      ),
      _react2.default.createElement(_divider2.default, { text: __("Data version") }),
      _react2.default.createElement(
        _reactBootstrap.Grid,
        null,
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 12 },
          fcds.map(fcd => fcd ? _react2.default.createElement(
            'p',
            { key: fcd[0] },
            `${fcd[0]}: ${fcd[1]}`
          ) : null)
        ),
        _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 12 },
          _react2.default.createElement(
            _reactBootstrap.Button,
            { onClick: this.updateData('reload') },
            __("Update data")
          )
        )
      ),
      _react2.default.createElement(_divider2.default, { text: __('Performance Monitor') }),
      _react2.default.createElement(
        _reactBootstrap.Col,
        { xs: 12 },
        _react2.default.createElement(AppMetrics, null)
      ),
      _react2.default.createElement(_divider2.default, { text: 'Contributors' }),
      _react2.default.createElement(
        _reactBootstrap.Grid,
        null,
        CONST.contributors.map((e, i) => _react2.default.createElement(
          _reactBootstrap.Col,
          { xs: 2, key: i },
          _react2.default.createElement('img', { className: 'avatar-img', src: e.avatar, onClick: _electron.shell.openExternal.bind(this, e.link), title: e.name })
        ))
      ),
      _react2.default.createElement(_divider2.default, { text: 'Thanks To' }),
      _react2.default.createElement(
        _reactBootstrap.Grid,
        { className: 'thanks-to' },
        CONST.thanksTo.map((e, i) => _react2.default.createElement(
          'div',
          { className: 'div-row thanks-to-item', key: i },
          _react2.default.createElement(
            'div',
            { className: 'thanks-to-img-container' },
            _react2.default.createElement('img', { className: 'thanks-to-img', src: e.avatar, style: e.extraCSS, onClick: _electron.shell.openExternal.bind(this, e.link), title: e.name })
          ),
          _react2.default.createElement(
            'div',
            { className: 'thanks-to-container' },
            _react2.default.createElement(
              'b',
              null,
              e.name
            ),
            _react2.default.createElement(
              'p',
              null,
              e.description
            )
          )
        ))
      )
    );
  }
});

exports.default = Others;
module.exports = exports['default'];