/**
 * A utility that allows us to mock the DOM and run plugins exactly as they
 * are written.
 *
 * This module changes the behavior of "require," allowing us to stub out
 * imports of jQuery and the annotations module.
 *
 * Additionally, the module exposes a number of variables from the jsdom
 * instance to the global namespace. Allowing us to code as if we're in
 * a browser environment (i.e. using "document") while skipping the webpack
 * bundling step.
 */

let fs = require("fs");
let jsdom = require("jsdom");
let m = require("module");
let annotateStub = require("./annotate-stub");

let axsSrc = fs.readFileSync(
    "./node_modules/accessibility-developer-tools/dist/js/axs_testing.js",
    "utf-8");
let jquerySrc = fs.readFileSync(
    "./node_modules/jquery/dist/jquery.min.js", "utf-8");
let jqueryExtSrc = fs.readFileSync(
    "./test/mock-dom/jquery-extensions.js", "utf-8");

exports.createDom = function(callback) {
    // Create a jsDom environment from the given HTML and initialize some
    // JavaScript on the page.
    jsdom.env({
        html: "",
        src: [axsSrc, jquerySrc, jqueryExtSrc],
        done: function(errors, window) {
            // Expose some fields from `window` onto the global namespace
            //
            // TODO: Currently we add fields here (see "Node") as we need
            // them, but this may prove tricky to maintain.
            global.__proto__ = {
                document: window.document,
                $: window.jQuery,
                axs: window.axs,
                Node: window.Node,
            };

            // Overwrite the default module loader.
            //
            // Here we intercept `require()` calls to stub out the annotations
            // module, as well as provide our own copy of jQuery.
            //
            // First, store a reference to the original module loader so we
            // can still use it.
            const originalLoader = m._load;

            m._load = function(request, parent, isMain) {
                if (/annotate$/.test(request)) {
                    // Return a stub of the annotations module to plugins that
                    // `require` it
                    return annotateStub;
                } else if (request === "jquery") {
                    // Return this window's jQuery instance to plugins that
                    // require "jquery"
                    return window.jQuery;
                } else if (!/(\.less|\.handlebars)$/.test(request)) {
                    // Defer to the original loader for everything else, with
                    // the exception that we'll ignore webpack's less and
                    // handlebars loaders
                    return originalLoader(request, parent, isMain);
                }
            };

            callback();
        }
    });
};

@@ -1304,61 +1304,48 @@
 ere 
-(see %22Node%22) as we need%0A            // them, but this
+as we need them, but this%0A            //
  may
@@ -1394,46 +1394,16 @@
 bal.
-__proto__ = %7B%0A                
 document
 : wi
@@ -1398,17 +1398,18 @@
 document
-:
+ =
  window.
@@ -1416,19 +1416,18 @@
 document
-,%0A 
+;%0A
         
@@ -1434,13 +1434,18 @@
     
-   $:
+global.$ =
  win
@@ -1454,17 +1454,17 @@
 w.jQuery
-,
+;
 %0A       
@@ -1472,16 +1472,20 @@
     
-    axs:
+global.axs =
  win
@@ -1491,17 +1491,17 @@
 ndow.axs
-,
+;
 %0A       
@@ -1509,17 +1509,21 @@
     
-    
+global.
 Node
-:
+ =
  win
@@ -1534,23 +1534,8 @@
 Node
-,%0A            %7D
 ;%0A%0A 

set properties directly on `global` instead of its `__proto__`