"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 _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

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("../../MemoryFile");
var mlink = require("../../link");
var DeviceManager = require("../../link/managers/device_manager");
var URL = require("url");
var config = require("../../config");
var protocols = {
  "http:": require("http"),
  "https:": require("https")
};

var _require = require("../../util"),
    logger = _require.logger;

var httpRouter = new Router();

var syncCallNativeIndex = 0;
var syncCallJSIndex = 0;
var SyncTerminal = mlink.Terminal.SyncTerminal;
var syncNativeHub = mlink.Hub.get("sync.native");
var syncV8Hub = mlink.Hub.get("sync.v8");

var rSourceMapDetector = /\.map$/;

var getRemote = 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": "Weex/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);
    });
  });
};

httpRouter.get("/source/*", function () {
  var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(ctx, next) {
    var path, content, query, file;
    return _regenerator2.default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            path = ctx.params[0];

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

            logger.verbose("Fetch sourcemap " + path);
            content = void 0;
            _context.prev = 4;
            _context.next = 7;
            return getRemote("http://" + path);

          case 7:
            content = _context.sent;
            _context.next = 13;
            break;

          case 10:
            _context.prev = 10;
            _context.t0 = _context["catch"](4);

            logger.verbose("Failed to fetch, reason: " + _context.t0.stack);

          case 13:
            if (!content) {
              ctx.response.status = 404;
            } else {
              ctx.response.status = 200;
              ctx.type = "text/javascript";
              ctx.set("Access-Control-Allow-Origin", "*");
              ctx.response.body = content;
            }
            _context.next = 20;
            break;

          case 16:
            query = ctx.request.url.split("?");

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

            if (file) {
              ctx.response.status = 200;
              ctx.type = "text/javascript";
              ctx.response.body = file.getContent();
            } else {
              ctx.response.status = 404;
            }

          case 20:
            _context.next = 22;
            return next();

          case 22:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, undefined, [[4, 10]]);
  }));

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

httpRouter.post("/syncCallNative/*", function () {
  var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(ctx, next) {
    var idx, payload, channelId, device, terminal, data;
    return _regenerator2.default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            idx = syncCallNativeIndex++;
            payload = ctx.request.body;
            channelId = ctx.params[0];
            device = DeviceManager.getDevice(channelId);

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

            terminal = new SyncTerminal();

            terminal.channelId = channelId;
            syncNativeHub.join(terminal, false);
            payload.params.syncId = 100000 + idx;
            payload.id = 100000 + idx;
            _context2.next = 12;
            return terminal.send(payload);

          case 12:
            data = _context2.sent;

            ctx.response.status = 200;
            ctx.type = "application/json";
            ctx.response.body = (0, _stringify2.default)(data);
            _context2.next = 19;
            break;

          case 18:
            ctx.response.status = 500;

          case 19:
            _context2.next = 21;
            return next();

          case 21:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2, undefined);
  }));

  return function (_x3, _x4) {
    return _ref2.apply(this, arguments);
  };
}());

httpRouter.post("/syncCallJS/*", function () {
  var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(ctx, next) {
    var idx, channelId, payload, device, instanceId, terminal, data;
    return _regenerator2.default.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            idx = syncCallJSIndex++;
            channelId = ctx.params[0];
            payload = ctx.request.body;
            device = DeviceManager.getDevice(channelId);
            instanceId = payload.params.args[0];

            if (!device) {
              _context3.next = 24;
              break;
            }

            terminal = new SyncTerminal();
            data = void 0;

            terminal.channelId = channelId;
            syncV8Hub.join(terminal, false);
            payload.params.syncId = 100000 + idx;
            payload.id = 100000 + idx;

            if (!(config.ACTIVE_INSTANCEID !== instanceId)) {
              _context3.next = 16;
              break;
            }

            data = [{}];
            _context3.next = 19;
            break;

          case 16:
            _context3.next = 18;
            return terminal.send(payload);

          case 18:
            data = _context3.sent;

          case 19:
            ctx.response.status = 200;
            ctx.type = "application/json";
            ctx.response.body = (0, _stringify2.default)(data.ret);
            _context3.next = 25;
            break;

          case 24:
            ctx.response.status = 500;

          case 25:
            _context3.next = 27;
            return next();

          case 27:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee3, undefined);
  }));

  return function (_x5, _x6) {
    return _ref3.apply(this, arguments);
  };
}());

module.exports = httpRouter;