#!/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>
    // Define controllers.
    class AppCtrl {
      url = null;
      urlInput = null;
      urlInputController = null;
      urlInputValidators = null;
      duration = '(N/A)';

      constructor() {
	this.setUrlWithSlashesPowerOf2Exponent(20);
      }

      $postLink() {
	// Remove the default validators (which include the URL validator) to prevent
	// the browser's freezing during entering a value and run validation on demand.
	this.urlInputController = this.urlInput.controller('ngModel');
      }

      setUrlWithSlashesPowerOf2Exponent(exponent) {
	this.url = 'scheme:'+('/'.repeat(2 ** exponent));
      }

      validateUrl() {
	  // Temporarily restore the default validators (which include the URL validator)
	  // and run validation on demand (while measuring the time it takes).
	  const start = Date.now();
	  this.urlInputController.$validate();
	  const end = Date.now();

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

    // Define and configure the app.
    const app = angular
	.module('app', [])
	.controller('AppCtrl', AppCtrl);
    setTimeout(() => {
       angular.element(document.body).scope().$ctrl.setUrlWithSlashesPowerOf2Exponent(20);
       angular.element(document.body).scope().$ctrl.validateUrl();
     } , 200);
  </script>
</head>
<body ng-app="app" ng-controller="AppCtrl as $ctrl">
<input type="url" ng-ref="$ctrl.urlInput" ng-model="$ctrl.url" />
</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']);
  });
});

