'use strict';

var _stringify = require('babel-runtime/core-js/json/stringify');

var _stringify2 = _interopRequireDefault(_stringify);

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

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

var Router = require('koa-router');
var MemoryFile = require('../../lib/memory_file');
var mlink = require('../../mlink/midware');
var DeviceManager = require('../../mlink/managers/device_manager');
var URL = require('url');
var config = require('../../lib/config');

var _require = require('../../util/wrapper'),
    bundleWrapper = _require.bundleWrapper;

var protocols = {
  'http:': require('http'),
  'https:': require('https')
};

var _require2 = require('../../util/logger'),
    logger = _require2.logger;

var httpRouter = new Router();

function getRemote(url) {
  return new _promise2.default(function (resolve, reject) {
    var urlObj = URL.parse(url);
    (protocols[urlObj.protocol] || protocols['http:']).get({
      hostname: urlObj.hostname,
      port: urlObj.port,
      path: urlObj.path,
      method: 'GET',
      headers: {
        'User-Agent': 'Atom/1.0.0'
      }
    }, function (res) {
      var chunks = [];
      res.on('data', function (chunk) {
        chunks.push(chunk);
      });
      res.on('end', function () {
        resolve(Buffer.concat(chunks).toString());
        chunks = null;
      });
    }).on('error', function (e) {
      reject(e);
    });
  });
}
var rSourceMapDetector = /\.map$/;
httpRouter.get('/source/*', /*#__PURE__*/_regenerator2.default.mark(function _callee(next) {
  var path, content, query, file, _content;

  return _regenerator2.default.wrap(function _callee$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          path = this.params[0];

          if (!rSourceMapDetector.test(path)) {
            _context.next = 9;
            break;
          }

          logger.verbose('Fetch sourcemap ' + path);
          _context.next = 5;
          return getRemote('http://' + path);

        case 5:
          content = _context.sent;

          if (!content) {
            this.response.status = 404;
          } else {
            this.response.status = 200;
            this.type = 'application/x-javascript';
            this.set('Access-Control-Allow-Origin', '*');
            this.response.body = content;
          }
          _context.next = 27;
          break;

        case 9:
          query = this.request.url.split('?');

          query = query[1] ? '?' + query.slice(1).join('?') : '';
          file = MemoryFile.get(path + query);

          if (!file) {
            _context.next = 26;
            break;
          }

          this.response.status = 200;
          this.type = 'application/x-javascript';

          if (!(file.url && config.proxy)) {
            _context.next = 23;
            break;
          }

          logger.verbose('Fetch jsbundle ' + file.url);
          _context.next = 19;
          return getRemote(file.url).catch(function (e) {
            // If file not found or got other http error.
            logger.verbose(e);
          });

        case 19:
          _content = _context.sent;

          if (!_content) {
            this.response.body = file.getContent();
          } else {
            this.response.body = bundleWrapper(_content, file.getUrl());
          }
          _context.next = 24;
          break;

        case 23:
          this.response.body = file.getContent();

        case 24:
          _context.next = 27;
          break;

        case 26:
          this.response.status = 404;

        case 27:
        case 'end':
          return _context.stop();
      }
    }
  }, _callee, this);
}));

var syncApiIndex = 0;
var SyncTerminal = mlink.Terminal.SyncTerminal;
var syncHub = mlink.Hub.get('sync');
httpRouter.post('/syncApi', /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
  var idx, payload, device, terminal, data;
  return _regenerator2.default.wrap(function _callee2$(_context2) {
    while (1) {
      switch (_context2.prev = _context2.next) {
        case 0:
          idx = syncApiIndex++;
          payload = this.request.body;
          device = DeviceManager.getDevice(payload.channelId);

          if (!device) {
            _context2.next = 17;
            break;
          }

          terminal = new SyncTerminal();

          terminal.channelId = payload.channelId;
          syncHub.join(terminal, true);
          payload.params.syncId = 100000 + idx;
          payload.id = 100000 + idx;
          _context2.next = 11;
          return terminal.send(payload);

        case 11:
          data = _context2.sent;

          this.response.status = 200;
          this.type = 'application/json';
          this.response.body = (0, _stringify2.default)(data);
          _context2.next = 18;
          break;

        case 17:
          this.response.status = 500;

        case 18:
        case 'end':
          return _context2.stop();
      }
    }
  }, _callee2, this);
}));
module.exports = httpRouter;