"use strict";

var _require = require("lodash"),
  times = _require.times;
var _require2 = require("../utils.js"),
  createDoc = _require2.createDoc,
  expect = _require2.expect,
  createXmlTemplaterDocxNoRender = _require2.createXmlTemplaterDocxNoRender,
  browserMatches = _require2.browserMatches;
var inspectModule = require("../../inspect-module.js");

/* eslint-disable-next-line no-process-env */
if (!process.env.SPEED_TEST) {
  describe("Speed test", function () {
    it("should be fast for simple tags", function () {
      var content = "<w:t>tag {age}</w:t>";
      var docs = [];
      for (var i = 0; i < 100; i++) {
        docs.push(createXmlTemplaterDocxNoRender(content, {
          tags: {
            age: 12
          }
        }));
      }
      var time = new Date();
      for (var _i = 0; _i < 100; _i++) {
        docs[_i].render();
      }
      var duration = new Date() - time;
      expect(duration).to.be.below(400);
    });
    it("should be fast for simple tags with huge content", function () {
      var content = "<w:t>tag {age}</w:t>";
      var i;
      var result = [];
      for (i = 1; i <= 10000; i++) {
        result.push("bla");
      }
      var prepost = result.join("");
      content = prepost + content + prepost;
      var docs = [];
      for (i = 0; i < 20; i++) {
        docs.push(createXmlTemplaterDocxNoRender(content, {
          tags: {
            age: 12
          }
        }));
      }
      var time = new Date();
      for (i = 0; i < 20; i++) {
        docs[i].render();
      }
      var maxDuration = 400;
      if (browserMatches(/chrome (73|71)/)) {
        maxDuration = 600;
      }
      var duration = new Date() - time;
      expect(duration).to.be.below(maxDuration);
    });
    it("should be fast for loop tags", function () {
      var content = "<w:t>{#users}{name}{/users}</w:t>";
      var users = [];
      for (var i = 1; i <= 1000; i++) {
        users.push({
          name: "foo"
        });
      }
      var doc = createXmlTemplaterDocxNoRender(content, {
        tags: {
          users: users
        }
      });
      var time = new Date();
      doc.render();
      var duration = new Date() - time;
      var maxDuration = 100;
      if (browserMatches(/firefox (55|60|64|65)/) || browserMatches(/MicrosoftEdge (16)/)) {
        maxDuration = 150;
      }
      expect(duration).to.be.below(maxDuration);
    });
    it("should be fast for nested loop tags", function () {
      var result = [];
      for (var i = 1; i <= 300; i++) {
        result.push("\n\t\t<w:proofErr w:type=\"spellEnd\"/>\n\t\t<w:r w:rsidRPr=\"0000000\">\n\t\t<w:rPr>\n\t\t<w:rFonts w:asciiTheme=\"minorHAnsi\" w:eastAsia=\"Times New Roman\" w:hAnsiTheme=\"minorHAnsi\" w:cs=\"Arial\"/>\n\t\t<w:sz w:val=\"22\"/>\n\t\t<w:szCs w:val=\"22\"/>\n\t\t<w:lang w:eastAsia=\"es-ES\"/>\n\t\t</w:rPr>\n\t\t<w:t xml:space=\"preserve\">{#users} Names : {user}</w:t>\n\t\t<w:t xml:space=\"preserve\">{/}</w:t>\n\t\t</w:r>\n\t\t");
      }
      var prepost = result.join("");
      var content = "<w:p><w:r><w:t>{#foo}</w:t></w:r>".concat(prepost, "<w:r><w:t>{/}</w:t></w:r></w:p>");
      var users = [{
        name: "John"
      }, {
        name: "Mary"
      }];
      var doc = createXmlTemplaterDocxNoRender(content, {
        tags: {
          users: users
        }
      });
      var time = new Date();
      doc.render();
      var duration = new Date() - time;
      var maxDuration = 300;
      if (browserMatches(/MicrosoftEdge (16|17|18)/) || browserMatches(/internet explorer (10|11)/) || browserMatches(/chrome (58|71|73|75)/) || browserMatches(/iphone 10.3/)) {
        maxDuration = 500;
      }
      expect(duration).to.be.below(maxDuration);
    });
    /* eslint-disable-next-line no-process-env */
    if (!process.env.FAST) {
      it("should not exceed call stack size for big document with a few rawxml tags", function () {
        this.timeout(30000);
        var result = [];
        var normalContent = "<w:p><w:r><w:t>foo</w:t></w:r></w:p>";
        var rawContent = "<w:p><w:r><w:t>{@raw}</w:t></w:r></w:p>";
        for (var i = 1; i <= 30000; i++) {
          if (i % 100 === 1) {
            result.push(rawContent);
          }
          result.push(normalContent);
        }
        var content = result.join("");
        var users = [];
        var doc = createXmlTemplaterDocxNoRender(content, {
          tags: {
            users: users
          }
        });
        var now = new Date();
        doc.compile();
        var compileDuration = new Date() - now;
        if (typeof window === "undefined") {
          // Skip this assertion in the browser
          expect(compileDuration).to.be.below(3000);
        }
        now = new Date();
        doc.render();
        var renderDuration = new Date() - now;
        expect(renderDuration).to.be.below(2000);
      });
      it.skip("should not exceed call stack size for big document with many rawxml tags", function () {
        this.timeout(30000);
        var result = [];
        var normalContent = "<w:p><w:r><w:t>foo</w:t></w:r></w:p>";
        var rawContent = "<w:p><w:r><w:t>{@raw}</w:t></w:r></w:p>";
        for (var i = 1; i <= 50000; i++) {
          if (i % 2 === 1) {
            result.push(rawContent);
          }
          result.push(normalContent);
        }
        var content = result.join("");
        var users = [];
        var doc = createXmlTemplaterDocxNoRender(content, {
          tags: {
            users: users
          }
        });
        var now = new Date();
        doc.compile();
        var compileDuration = new Date() - now;
        if (typeof window === "undefined") {
          // Skip this assertion in the browser
          expect(compileDuration).to.be.below(3000);
        }
        now = new Date();
        doc.render();
        var maxRenderDuration = 2000;
        var renderDuration = new Date() - now;
        if (browserMatches(/internet explorer (10|11)/) || browserMatches(/MicrosoftEdge (16|17|18)/)) {
          maxRenderDuration = 3000;
        }
        if (browserMatches(/firefox (68)/)) {
          maxRenderDuration = 2500;
        }
        expect(renderDuration).to.be.below(maxRenderDuration);
      });
      describe("Inspect module", function () {
        it("should not be slow after multiple generations", function () {
          var duration = 0;
          var iModule = inspectModule();
          for (var i = 0; i < 10; i++) {
            var doc = createDoc("tag-product-loop.docx");
            var startTime = new Date();
            doc.attachModule(iModule);
            var data = {
              nom: "Doe",
              prenom: "John",
              telephone: "0652455478",
              description: "New Website",
              offre: times(20000, function (i) {
                return {
                  prix: 1000 + i,
                  nom: "Acme" + i
                };
              })
            };
            doc.setData(data);
            doc.compile();
            doc.render();
            duration += new Date() - startTime;
          }
          var maxInspectDuration = 750;
          if (browserMatches(/firefox (55)/) || browserMatches(/MicrosoftEdge (16|17|18)/)) {
            maxInspectDuration = 1000;
          }
          expect(duration).to.be.below(maxInspectDuration);
        });
      });
      it("should not be slow when having many loops with resolveData", function () {
        this.timeout(30000);
        var OldPromise = global.Promise;
        var resolveCount = 0;
        var allCount = 0;
        var parserCount = 0;
        var parserGetCount = 0;
        global.Promise = function (arg1, arg2) {
          return new OldPromise(arg1, arg2);
        };
        global.Promise.resolve = function (arg1) {
          resolveCount++;
          return OldPromise.resolve(arg1);
        };
        global.Promise.all = function (arg1) {
          allCount++;
          return OldPromise.all(arg1);
        };
        var doc = createDoc("multi-level.docx");
        doc.setOptions({
          paragraphLoop: true,
          parser: function parser(tag) {
            parserCount++;
            return {
              get: function get(scope) {
                parserGetCount++;
                return scope[tag];
              }
            };
          }
        });
        var start = +new Date();
        doc.compile();
        var stepCompile = +new Date() - start;
        start = +new Date();
        var multiplier = 20;
        var total = Math.pow(multiplier, 3);
        var data = {
          l1: times(multiplier),
          l2: times(multiplier),
          l3: times(multiplier, function () {
            return {
              content: "Hello"
            };
          })
        };
        return doc.resolveData(data).then(function () {
          var stepResolve = +new Date() - start;
          start = +new Date();
          doc.render();
          var stepRender = +new Date() - start;
          expect(stepCompile).to.be.below(100);
          var maxResolveTime = 2000;
          if (browserMatches(/MicrosoftEdge (16|17|18)/)) {
            maxResolveTime = 20000;
          }
          if (browserMatches(/firefox (55|89)/)) {
            maxResolveTime = 4000;
          }
          expect(stepResolve).to.be.below(maxResolveTime);
          var maxRenderTime = 1000;
          if (browserMatches(/firefox (55|60|64|65|66|67)/) || browserMatches(/iphone 10.3/) || browserMatches(/MicrosoftEdge (16|17|18)/)) {
            maxRenderTime = 2000;
          }
          expect(stepRender).to.be.below(maxRenderTime);
          expect(parserCount).to.be.equal(4);
          // 20**3 + 20**2 *3 + 20 * 2 + 1  = 9241
          expect(parserGetCount).to.be.equal(9241);
          expect(resolveCount).to.be.within(total, total * 1.2);
          expect(allCount).to.be.within(total, total * 1.2);
          global.Promise = OldPromise;
        });
      });
    }
  });
}