#!/usr/bin/env node

const { JSDOM, VirtualConsole } = require("jsdom");
const fs = require("fs");

const angularPath = "/usr/share/javascript/angular.js/angular.min.js";
const angularResource = "/usr/share/javascript/angular.js/angular-resource.min.js";
const angularMocks = "/usr/share/javascript/angular.js/angular-mocks.js";

const angularJS          = fs.readFileSync(angularPath, "utf-8");
const angularResourceJS  = fs.readFileSync(angularResource, "utf-8");
const angularMocksJS     = fs.readFileSync(angularMocks, "utf-8");

const html = `
<!DOCTYPE html>
<html>
<head>
  <script>${angularJS}</script>
  <script>${angularResourceJS}</script>
  <script>${angularMocksJS}</script>

  <script>
  class AppCtrl {
    regexPattern = null;
    duration = '(N/A)';

    constructor() {
      this.setRegexPatternWithCharsPowerOf2Exponent(17);
      setTimeout(() => {
           console.log("[E] Timeout");
           windows.process.exit(3);
         }, 40 * 1000)
      this.runTest();
    }

    setRegexPatternWithCharsPowerOf2Exponent(exponent) {
      this.regexPattern = 'x'.repeat(2 ** exponent);
    }

    runTest() {
      // Escape spacial regular expression characters.
      const pattern = this.regexPattern.replace(/[-.?*+^$|\\\/(){}[\]]/g, '\\$&');
      const regex = new RegExp(pattern);

      const start = Date.now();
      angular.copy(regex);
      const end = Date.now();

      this.duration = ((end - start) / 1000).toFixed(2);
      console.log(\`Query setup time: \${this.duration} sec\`);
      if (this.duration > 3) {
        console.log("[E] It took too long!");
        window.process.exit(2);
      } else {
        window.process.exit(0);
      }
    }
  }

  angular
      .module('app', [])
      .controller('AppCtrl', AppCtrl);
  </script>
</head>
<body ng-app="app" ng-controller="AppCtrl as ctrl">
</body>
</html>
`;

const virtualConsole = new VirtualConsole();
virtualConsole.sendTo(console);

const dom = new JSDOM(html, {
  runScripts: "dangerously",
  resources: "usable",
  virtualConsole
});
dom.window.process = process;

dom.window.document.addEventListener("DOMContentLoaded", () => {
  const angular = dom.window.angular;
  angular.element(dom.window.document).ready(() => {
    angular.bootstrap(dom.window.document, ['app']);
  });
});

