import _regeneratorRuntime from "@babel/runtime/regenerator";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import screenJs from '../../lib/screen';
import regeneratorRuntimePolyfill from 'raw-loader!regenerator-runtime/runtime';
/**
 * @param html:String
 * @param files: ImmutableFile[]
 * @return Promise<String>
 *
 * iframe にユーザーが入力したHTMLに、次の操作を加える
 * 0. window.feeles
 * 1. headタグの一番上に screenJs を埋め込む
 * 2. src 属性を Data URL に差し替える
 * REMOVED: 3. screenJs のすぐ下で、全てのスクリプトを define する
 * 4. スクリプトタグの src 属性を requirejs を Data URL に差し替える
 * 5. a 要素の href 属性を feeles.replace の Data URL に差し替える
 * 6. regeneratorRuntime
 */

export default
/*#__PURE__*/
(function () {
  var _ref = _asyncToGenerator(
  /*#__PURE__*/
  _regeneratorRuntime.mark(function _callee(html) {
    var files,
        parser,
        doc,
        appendScript,
        binaries,
        _iteratorNormalCompletion,
        _didIteratorError,
        _iteratorError,
        _loop,
        _iterator,
        _step,
        _ret,
        _arr,
        _loop2,
        _i,
        _ret2,
        _arr2,
        _loop3,
        _i2,
        _ret3,
        _arr3,
        _i3,
        node,
        href,
        _args3 = arguments;

    return _regeneratorRuntime.wrap(function _callee$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            files = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : [];
            parser = new DOMParser();
            doc = parser.parseFromString(html, 'text/html');

            appendScript = function (lastNode) {
              return function (text) {
                var script = doc.createElement('script');
                script.type = 'text/javascript';
                script.text = text;
                doc.head.insertBefore(script, lastNode && lastNode.nextSibling);
                lastNode = script;
              };
            }(doc.head.firstChild); // 0. window.feeles


            appendScript("window.feeles = { env: {} };"); // 1. headタグの一番上に screenJs を埋め込む

            appendScript(screenJs()); // 2. src 属性を Data URL に差し替える

            binaries = _toConsumableArray(doc.images);
            _iteratorNormalCompletion = true;
            _didIteratorError = false;
            _iteratorError = undefined;
            _context3.prev = 10;
            _loop =
            /*#__PURE__*/
            _regeneratorRuntime.mark(function _loop() {
              var node, file, dataURL;
              return _regeneratorRuntime.wrap(function _loop$(_context) {
                while (1) {
                  switch (_context.prev = _context.next) {
                    case 0:
                      node = _step.value;
                      file = files.find(function (file) {
                        return file.name === node.getAttribute('src');
                      });

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

                      return _context.abrupt("return", "continue");

                    case 4:
                      _context.next = 6;
                      return file.toDataURL();

                    case 6:
                      dataURL = _context.sent;
                      node.setAttribute('src', dataURL);

                    case 8:
                    case "end":
                      return _context.stop();
                  }
                }
              }, _loop, this);
            });
            _iterator = binaries[Symbol.iterator]();

          case 13:
            if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
              _context3.next = 21;
              break;
            }

            return _context3.delegateYield(_loop(), "t0", 15);

          case 15:
            _ret = _context3.t0;

            if (!(_ret === "continue")) {
              _context3.next = 18;
              break;
            }

            return _context3.abrupt("continue", 18);

          case 18:
            _iteratorNormalCompletion = true;
            _context3.next = 13;
            break;

          case 21:
            _context3.next = 27;
            break;

          case 23:
            _context3.prev = 23;
            _context3.t1 = _context3["catch"](10);
            _didIteratorError = true;
            _iteratorError = _context3.t1;

          case 27:
            _context3.prev = 27;
            _context3.prev = 28;

            if (!_iteratorNormalCompletion && _iterator.return != null) {
              _iterator.return();
            }

          case 30:
            _context3.prev = 30;

            if (!_didIteratorError) {
              _context3.next = 33;
              break;
            }

            throw _iteratorError;

          case 33:
            return _context3.finish(30);

          case 34:
            return _context3.finish(27);

          case 35:
            // 2.1 link 要素の href 属性を Data URL に差し替える
            _arr = _toConsumableArray(doc.querySelectorAll('link'));
            _loop2 =
            /*#__PURE__*/
            _regeneratorRuntime.mark(function _loop2() {
              var node, file, replaced;
              return _regeneratorRuntime.wrap(function _loop2$(_context2) {
                while (1) {
                  switch (_context2.prev = _context2.next) {
                    case 0:
                      node = _arr[_i];
                      file = files.find(function (file) {
                        return file.name === node.getAttribute('href');
                      });

                      if (file) {
                        _context2.next = 4;
                        break;
                      }

                      return _context2.abrupt("return", "continue");

                    case 4:
                      if (!(file.is('css') && file.text.indexOf('url') >= 0)) {
                        _context2.next = 18;
                        break;
                      }

                      _context2.t0 = file;
                      _context2.next = 8;
                      return replaceUrls(file.text, files);

                    case 8:
                      _context2.t1 = _context2.sent;
                      _context2.t2 = {
                        text: _context2.t1
                      };
                      replaced = _context2.t0.set.call(_context2.t0, _context2.t2);
                      _context2.t3 = node;
                      _context2.next = 14;
                      return replaced.toDataURL();

                    case 14:
                      _context2.t4 = _context2.sent;

                      _context2.t3.setAttribute.call(_context2.t3, 'href', _context2.t4);

                      _context2.next = 23;
                      break;

                    case 18:
                      _context2.t5 = node;
                      _context2.next = 21;
                      return file.toDataURL();

                    case 21:
                      _context2.t6 = _context2.sent;

                      _context2.t5.setAttribute.call(_context2.t5, 'href', _context2.t6);

                    case 23:
                    case "end":
                      return _context2.stop();
                  }
                }
              }, _loop2, this);
            });
            _i = 0;

          case 38:
            if (!(_i < _arr.length)) {
              _context3.next = 46;
              break;
            }

            return _context3.delegateYield(_loop2(), "t2", 40);

          case 40:
            _ret2 = _context3.t2;

            if (!(_ret2 === "continue")) {
              _context3.next = 43;
              break;
            }

            return _context3.abrupt("continue", 43);

          case 43:
            _i++;
            _context3.next = 38;
            break;

          case 46:
            // 4. スクリプトタグの src 属性を requirejs を Data URL に差し替える
            _arr2 = _toConsumableArray(doc.scripts);

            _loop3 = function _loop3() {
              var node = _arr2[_i2];
              if (node.type && node.type !== 'text/javascript') return "continue";
              var file = files.find(function (file) {
                return file.name === node.getAttribute('src');
              });
              if (!file) return "continue";
              var dataURL = 'data:text/javascript;charset=UTF-8,' + encodeURIComponent(requireTemplate(file.moduleName));
              node.setAttribute('src', dataURL);
            };

            _i2 = 0;

          case 49:
            if (!(_i2 < _arr2.length)) {
              _context3.next = 56;
              break;
            }

            _ret3 = _loop3();

            if (!(_ret3 === "continue")) {
              _context3.next = 53;
              break;
            }

            return _context3.abrupt("continue", 53);

          case 53:
            _i2++;
            _context3.next = 49;
            break;

          case 56:
            // 5. a 要素の href 属性を feeles.replace に差し替える
            _arr3 = _toConsumableArray(doc.links);
            _i3 = 0;

          case 58:
            if (!(_i3 < _arr3.length)) {
              _context3.next = 68;
              break;
            }

            node = _arr3[_i3];

            if (!(node.getAttribute('target') === '_blank')) {
              _context3.next = 62;
              break;
            }

            return _context3.abrupt("continue", 65);

          case 62:
            href = node.getAttribute('href') || '';
            node.setAttribute('href', '#');
            node.setAttribute('onclick', "feeles.replace('".concat(href, "')"));

          case 65:
            _i3++;
            _context3.next = 58;
            break;

          case 68:
            // 6. regeneratorRuntime
            appendScript(regeneratorRuntimePolyfill);
            return _context3.abrupt("return", doc.documentElement.outerHTML);

          case 70:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee, this, [[10, 23, 27, 35], [28,, 30, 34]]);
  }));

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

var requireTemplate = function requireTemplate(src) {
  return "requirejs(['".concat(src, "'])");
};

var replaceUrls =
/*#__PURE__*/
function () {
  var _ref2 = _asyncToGenerator(
  /*#__PURE__*/
  _regeneratorRuntime.mark(function _callee2(text) {
    var files,
        regExp,
        matches,
        _iteratorNormalCompletion2,
        _didIteratorError2,
        _iteratorError2,
        _loop4,
        _iterator2,
        _step2,
        _args5 = arguments;

    return _regeneratorRuntime.wrap(function _callee2$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            files = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : [];
            regExp = /url\(.*\)/g;
            matches = text.match(regExp);

            if (matches) {
              _context5.next = 5;
              break;
            }

            return _context5.abrupt("return", text);

          case 5:
            _iteratorNormalCompletion2 = true;
            _didIteratorError2 = false;
            _iteratorError2 = undefined;
            _context5.prev = 8;
            _loop4 =
            /*#__PURE__*/
            _regeneratorRuntime.mark(function _loop4() {
              var token, path, file, dataURL;
              return _regeneratorRuntime.wrap(function _loop4$(_context4) {
                while (1) {
                  switch (_context4.prev = _context4.next) {
                    case 0:
                      token = _step2.value;
                      path = token.substr(4, token.length - 5);
                      file = files.find(function (file) {
                        return file.name === path;
                      });

                      if (!file) {
                        _context4.next = 8;
                        break;
                      }

                      _context4.next = 6;
                      return file.toDataURL();

                    case 6:
                      dataURL = _context4.sent;
                      text = text.replace(token, "url(".concat(dataURL, ")"));

                    case 8:
                    case "end":
                      return _context4.stop();
                  }
                }
              }, _loop4, this);
            });
            _iterator2 = matches[Symbol.iterator]();

          case 11:
            if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
              _context5.next = 16;
              break;
            }

            return _context5.delegateYield(_loop4(), "t0", 13);

          case 13:
            _iteratorNormalCompletion2 = true;
            _context5.next = 11;
            break;

          case 16:
            _context5.next = 22;
            break;

          case 18:
            _context5.prev = 18;
            _context5.t1 = _context5["catch"](8);
            _didIteratorError2 = true;
            _iteratorError2 = _context5.t1;

          case 22:
            _context5.prev = 22;
            _context5.prev = 23;

            if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
              _iterator2.return();
            }

          case 25:
            _context5.prev = 25;

            if (!_didIteratorError2) {
              _context5.next = 28;
              break;
            }

            throw _iteratorError2;

          case 28:
            return _context5.finish(25);

          case 29:
            return _context5.finish(22);

          case 30:
            return _context5.abrupt("return", text);

          case 31:
          case "end":
            return _context5.stop();
        }
      }
    }, _callee2, this, [[8, 18, 22, 30], [23,, 25, 29]]);
  }));

  return function replaceUrls(_x2) {
    return _ref2.apply(this, arguments);
  };
}();