/* globals add_completion_callback, Promise, showdown, done, assert_true, Ajv, on_event */

/**
 * Creates a JSONtest object.  If the parameters are supplied
 * it also loads a referenced testFile, processes that file, loads any
 * referenced external assertions, and sets up event listeners to process the
 * user's test data.  The loading is done asynchronously via Promises.  The test
 * button's text is changed to Loading while it is processing, and to "Check
 * JSON" once the data is loaded.
 *
 * @constructor
 * @param {object} params
 * @param {string} [params.test] - object containing JSON test definition
 * @param {string} [params.testFile] - URI of a file with JSON test definition
 * @param {string} params.runTest - IDREF of an element that when clicked will run the test
 * @param {string} params.testInput - IDREF of an element that contains the JSON(-LD) to evaluate against the assertions in the test / testFile
 * @event DOMContentLoaded Calls init once DOM is fully loaded
 * @returns {object} Reference to the new object
 */

function JSONtest(params) {
  'use strict';

  this.Assertions = [];     // object that will contain the assertions to process
  this.AssertionText = "";  // string that holds the titles of all the assertions in use
  this.DescriptionText = "";
  this.Base = null;         // URI "base" for the test suite being run
  this.TestDir = null;      // URI "base" for the test case being run
  this.Params = null;       // paramaters passed in
  this.Promise = null;             // master Promise that resolves when intialization is complete
  this.Properties = null;   // testharness_properties from the opening window
  this.SkipFailures = [];   // list of assertionType values that should be skipped if their test would fail
  this.Test = null;         // test being run
  this.AssertionCounter = 0;// keeps track of which assertion is being processed

  this._assertionCache = [];// Array to put loaded assertions into
  this._assertionText = []; // Array of text or nested arrays of assertions
  this._loading = true;

  showdown.extension('strip', function() {
    return [
    { type: 'output',
      regex: /<p>/,
      replace: ''
    },
    { type: 'output',
      regex: /<\/p>$/,
      replace: ''
    }
    ];
  });


  this.markdown = new showdown.Converter({ extensions: [ 'strip' ] }) ;

  var pending = [] ;

  // set up in case DOM finishes loading early
  pending.push(new Promise(function(resolve) {
    on_event(document, "DOMContentLoaded", function() {
        resolve(true);
    }.bind(this));
  }.bind(this)));

  // create an ajv object that will stay around so that caching
  // of schema that are compiled just works
  this.ajv = new Ajv({allErrors: true, validateSchema: false}) ;

  // determine the base URI for the test collection.  This is
  // the top level folder in the test "document.location"

  var l = document.location;
  var p = l.pathname;
  this.TestDir = p.substr(0, 1+p.lastIndexOf('/'));
  this.Base = p.substr(0, 1+p.indexOf('/', 1));

  // if we are under runner, then there are props in the parent window
  //
  // if "output" is set in that, then pause at the end of running so the output
  // can be analyzed. @@@TODO@@@
  if (window && window.opener && window.opener.testharness_properties) {
    this.Properties = window.opener.testharness_properties;
  }

  this.Params = params;

  // if there is a list of definitions in the params,
  // include them
  if (this.Params.schemaDefs) {
    var defPromise = new Promise(function(resolve, reject) {
      var promisedSchema = this.Params.schemaDefs.map(function(item) {
        return this.loadDefinition(item);
      }.bind(this));

      // Once all the loadAssertion promises resolve...
      Promise.all(promisedSchema)
      .then(function (schemaContents) {
        this.ajv.addSchema(schemaContents);
        resolve(true);
      }.bind(this))
      .catch(function(err) {
        reject(err);
      }.bind(this));
    }.bind(this));
    // these schema need to load up too
    pending.push(defPromise) ;
  }

  // start by loading the test (it might be inline, but
  // loadTest deals with that
  pending.push(this.loadTest(params)
    .then(function(test) {
      // if the test is NOT an object, turn it into one
      if (typeof test === 'string') {
        test = JSON.parse(test) ;
      }

      this.Test = test;

      // Test should have information that we can put in the template

      if (test.description) {
        this.DescriptionText = test.description;
      }

      if (test.hasOwnProperty("skipFailures") && Array.isArray(test.skipFailures) ) {
        this.SkipFailures = test.skipFailures;
      }

      if (test.content) {
        // we have content
        if (typeof test.content === "string") {
          // the test content is a string - meaning it is a reference to a file of content
          var cPromise = new Promise(function(resolve, reject) {
            this.loadDefinition(test.content)
              .then(function(content) {
                if (typeof content === 'string') {
                  content = JSON.parse(content) ;
                }
                test.content = content;
                resolve(true);
              }.bind(this))
            .catch(function(err) {
              reject("Loading " + test.content + ": " + JSON.stringify(err));
            });

          }.bind(this));
          pending.push(cPromise);
        }
      }

      return new Promise(function(resolve, reject) {
        if (test.assertions &&
            typeof test.assertions === "object") {
          // we have at least one assertion
          // get the inline contents and the references to external files
          var assertFiles = this._assertionRefs(test.assertions);

          var promisedAsserts = assertFiles.map(function(item) {
            return this.loadAssertion(item);
          }.bind(this));

          // Once all the loadAssertion promises resolve...
          Promise.all(promisedAsserts)
          .then(function (assertContents) {
            // assertContents has assertions in document order

            var typeMap = {
              'must'   : "<b>[MANDATORY]</b> ",
              'may'    : "<b>[OPTIONAL]</b> ",
              'should' : "<b>[RECOMMENDED]</b> "
            };

            var assertIdx = 0;

            // populate the display of assertions that are being exercised
            // returns the list of top level assertions to walk through

            var buildList = function(assertions, level) {
              if (level === undefined) {
                level = 1;
              }

              // accumulate the assertions - but only when level is 0
              var list = [] ;

              var type = "";
              if (assertions) {
                if (typeof assertions === "object" && assertions.hasOwnProperty('assertions')) {
                  // this is a conditionObject
                  if (level === 0) {
                    list.push(assertContents[assertIdx]);
                  }
                  type = assertContents[assertIdx].hasOwnProperty('assertionType') ?
                    assertContents[assertIdx].assertionType : "must" ;

                  // ensure type defaults to must
                  if (!typeMap.hasOwnProperty(type)) {
                    type = "must";
                  }

                  this.AssertionText += "<li>" + typeMap[type] + this.markdown.makeHtml(assertContents[assertIdx++].title);
                  this.AssertionText += "<ol>";
                  buildList(assertions.assertions, level+1) ;
                  this.AssertionText += "</ol></li>\n";
                } else {
                  // it is NOT a conditionObject - must be an array
                  assertions.forEach( function(assert) {
                    if (typeof assert === "object" && Array.isArray(assert)) {
                      this.AssertionText += "<ol>";
                      // it is a nested list - recurse
                      buildList(assert, level+1) ;
                      this.AssertionText += "</ol>\n";
                    } else if (typeof assert === "object" &&
                        !Array.isArray(assert) &&
                        assert.hasOwnProperty('assertions')) {
                      if (level === 0) {
                        list.push(assertContents[assertIdx]);
                      }
                      type = assertContents[assertIdx].hasOwnProperty('assertionType') ?
                        assertContents[assertIdx].assertionType : "must" ;

                      // ensure type defaults to must
                      if (!typeMap.hasOwnProperty(type)) {
                        type = "must";
                      }

                      // there is a condition object in the array
                      this.AssertionText += "<li>" + typeMap[type] + this.markdown.makeHtml(assertContents[assertIdx++].title);
                      this.AssertionText += "<ol>";
                      buildList(assert, level+1) ; // capture the children too
                      this.AssertionText += "</ol></li>\n";
                    } else {
                      if (level === 0) {
                        list.push(assertContents[assertIdx]);
                      }
                      type = assertContents[assertIdx].hasOwnProperty('assertionType') ?
                        assertContents[assertIdx].assertionType : "must" ;

                      // ensure type defaults to must
                      if (!typeMap.hasOwnProperty(type)) {
                        type = "must";
                      }

                      this.AssertionText += "<li>" + typeMap[type] + this.markdown.makeHtml(assertContents[assertIdx++].title) + "</li>\n";
                    }
                  }.bind(this));
                }
              }
              return list;
            }.bind(this);

            // Assertions will ONLY contain the top level assertions
            this.Assertions = buildList(test.assertions, 0);
            resolve(true);
          }.bind(this))
          .catch(function(err) {
            reject(err);
          }.bind(this));
        } else {
          if (!test.assertions) {
            reject("Test has no assertion property");
          } else {
            reject("Test assertion property is not an Array");
          }
        }
      }.bind(this));
    }.bind(this)));

  this.Promise = new Promise(function(resolve, reject) {
    // once the DOM and the test / assertions are loaded... set us up
    Promise.all(pending)
    .then(function() {
      this.loading = false;
      this.init();
      resolve(this);
    }.bind(this))
    .catch(function(err) {
      // loading the components failed somehow - report the errors and mark the test failed
      test( function() {
        assert_true(false, "Loading of test components failed: " +JSON.stringify(err)) ;
      }, "Loading test components");
      done() ;
      reject("Loading of test components failed: "+JSON.stringify(err));
      return ;
    }.bind(this));
  }.bind(this));

  return this;
}

JSONtest.prototype = {

  /**
   * @listens click
   */
  init: function() {
    'use strict';
    // set up a handler
    var runButton = document.getElementById(this.Params.runTest) ;
    var closeButton = document.getElementById(this.Params.closeWindow) ;
    var testInput  = document.getElementById(this.Params.testInput) ;
    var assertion  = document.getElementById("assertion") ;
    var desc  = document.getElementById("testDescription") ;

    if (!this.loading) {
      if (runButton) {
        runButton.disabled = false;
        runButton.value = "Check JSON";
      }
      if (desc) {
        desc.innerHTML = this.DescriptionText;
      }
      if (assertion) {
        assertion.innerHTML = "<ol>" + this.AssertionText + "</ol>\n";
      }
    } else {
      window.alert("Loading did not finish before init handler was called!");
    }

    // @@@TODO@@@ implement the output showing handler
    if (0 && this.Properties && this.Properties.output && closeButton) {
      // set up a callback
      add_completion_callback( function() {
        var p = new Promise(function(resolve) {
          closeButton.style.display = "inline";
          closeButton.disabled = false;
          on_event(closeButton, "click", function() {
            resolve(true);
          });
        }.bind(this));
        p.then();
      }.bind(this));
    }

    if (runButton) {
      on_event(runButton, "click", function() {
        // user clicked
        var content = testInput.value;
        runButton.disabled = true;

        // make sure content is an object
        if (typeof content === "string") {
          try {
            content = JSON.parse(content) ;
          } catch(err) {
            // if the parsing failed, create a special test and mark it failed
            test( function() {
              assert_true(false, "Parse of JSON failed: " + err) ;
            }, "Parsing submitted input");
            // and just give up
            done();
            return ;
          }
        }

        // iterate over all of the tests for this instance
        this.runTests(this.Assertions, content);

        // explicitly tell the test framework we are done
        done();
      }.bind(this));
    }
  },

  // runTests - process tests
  /**
   * @param {object} assertions - List of assertions to process
   * @param {string} content - JSON(-LD) to be evaluated
   * @param {string} [testAction='continue'] - state of test processing (in parent when recursing)
   * @param {integer} [level=0] - depth of recursion since assertion lists can nest
   * @param {string} [compareWith='and'] - the way the results of the referenced assertions should be compared
   * @returns {string} - the testAction resulting from evaluating all of the assertions
   */
  runTests: function(assertions, content, testAction, level, compareWith) {
    'use strict';

    // level
    if (level === undefined) {
      level = 1;
    }

    // testAction
    if (testAction === undefined) {
      testAction = 'continue';
    }

    // compareWith
    if (compareWith === undefined) {
      compareWith = 'and';
    }

    var typeMap = {
      'must'   : "",
      'may'    : "INFORMATIONAL: ",
      'should' : "WARNING: "
    };


    // for each assertion (in order) load the external json schema if
    // one is referenced, or use the inline schema if supplied
    // validate content against the referenced schema

    var theResults = [] ;

    if (assertions) {

      assertions.forEach( function(assert, num) {

        var expected = assert.hasOwnProperty('expectedResult') ?
          assert.expectedResult : 'valid' ;
        var message = assert.hasOwnProperty('errorMessage') ?
          assert.errorMessage : "Result was not " + expected;
        var type = assert.hasOwnProperty('assertionType') ?
          assert.assertionType.toLowerCase() : "must" ;
        if (!typeMap.hasOwnProperty(type)) {
          type = "must";
        }

        // first - what is the type of the assert
        if (typeof assert === "object" && !Array.isArray(assert)) {
          if (assert.hasOwnProperty("compareWith") && assert.hasOwnProperty("assertions") && Array.isArray(assert.assertions) ) {
            // this is a comparisonObject
            var r = this.runTests(assert.assertions, content, testAction, level+1, assert.compareWith);
            // r is an object that contains, among other things, an array of results from the child assertions
            testAction = r.action;

            // evaluate the results against the compareWith setting
            var result = true;
            var data = r.results ;
            var i;

            if (assert.compareWith === "or") {
              result = false;
              for(i = 0; i < data.length; i++) {
                if (data[i]) {
                  result = true;
                }
              }
            } else {
              for(i = 0; i < data.length; i++) {
                if (!data[i]) {
                  result = false;
                }
              }
            }

            // create a test and push the result
            test(function() {
              var newAction = this.determineAction(assert, result) ;
              // next time around we will use this action
              testAction = newAction;

              var err = ";";

              if (testAction === 'abort') {
                err += "; Aborting execution of remaining assertions;";
              } else if (testAction === 'skip') {
                err += "; Skipping execution of remaining assertions at level " + level + ";";
              }

              if (result === false) {
                // test result was unexpected; use message
                assert_true(result, message + err);
              } else {
                assert_true(result, err) ;
              }
            }.bind(this), "" + level + ":" + (num+1) + " " + assert.title);
            // we are going to return out of this
            return;
          }
        } else if (typeof assert === "object" && Array.isArray(assert)) {
          // it is a nested list - recurse
          var o = this.runTests(assert, content, testAction, level+1);
          if (o.result && o.result === 'abort') {
            // we are bailing out
            testAction = 'abort';
          }
        }

        if (testAction === 'abort') {
          return {action: 'abort' };
        }

        var schemaName = "inline " + level + ":" + (num+1);

        if (typeof assert === "string") {
          // the assertion passed in is a file name; find it in the cache
          if (this._assertionCache[assert]) {
            assert = this._assertionCache[assert];
          } else {
            test( function() {
              assert_true(false, "Reference to assertion " + assert + " at level " + level + ":" + (num+1) + " unresolved") ;
            }, "Processing " + assert);
            return ;
          }
        }

        if (assert.assertionFile) {
          schemaName = "external file " + assert.assertionFile + " " + level + ":" + (num+1);
        }

        var validate = null;

        try {
          validate = this.ajv.compile(assert);
        }
        catch(err) {
          test( function() {
            assert_true(false, "Compilation of schema " + level + ":" + (num+1) + " failed: " + err) ;
          }, "Compiling " + schemaName);
          return ;
        }

        if (testAction === 'continue') {
          // a previous test told us to not run this test; skip it
          // test(function() { }, "SKIPPED: " + assert.title);
          // start an actual sub-test
          var valid = validate(content) ;

          var theResult = this.determineResult(assert, valid) ;

          // remember the result
          theResults.push(theResult);

          var newAction = this.determineAction(assert, theResult) ;
          // next time around we will use this action
          testAction = newAction;

          // only run the test if we are NOT skipping fails for some types
          // or the result is expected
          if ( theResult === true || !this.SkipFailures.includes(type) ) {
            test(function() {
              var err = ";";
              if (validate.errors !== null && !assert.hasOwnProperty("errorMessage")) {
                err = "; Errors: " + this.ajv.errorsText(validate.errors) + ";" ;
              }
              if (testAction === 'abort') {
                err += "; Aborting execution of remaining assertions;";
              } else if (testAction === 'skip') {
                err += "; Skipping execution of remaining assertions at level " + level + ";";
              }
              if (theResult === false) {
                // test result was unexpected; use message
                assert_true(theResult, typeMap[type] + message + err);
              } else {
                assert_true(theResult, err) ;
              }
            }.bind(this), "" + level + ":" + (num+1) + " " + assert.title);
          }
        }
      }.bind(this));
    }

    return { action: testAction, results: theResults} ;
  },

  determineResult: function(schema, valid) {
    'use strict';
    var r = 'valid' ;
    if (schema.hasOwnProperty('expectedResult')) {
      r = schema.expectedResult;
    }

    if (r === 'valid' && valid || r === 'invalid' && !valid) {
      return true;
    } else {
      return false;
    }
  },

  determineAction: function(schema, result) {
    'use strict';
    // mapping from results to actions
    var mapping = {
      'failAndContinue' : 'continue',
      'failAndSkip'    : 'skip',
      'failAndAbort'   : 'abort',
      'passAndContinue': 'continue',
      'passAndSkip'    : 'skip',
      'passAndAbort'   : 'abort'
    };

    // if the result was as expected, then just keep going
    if (result) {
      return 'continue';
    }

    var a = 'failAndContinue';

    if (schema.hasOwnProperty('onUnexpectedResult')) {
      a = schema.onUnexpectedResult;
    }

    if (mapping[a]) {
      return mapping[a];
    } else {
      return 'continue';
    }
  },

  // loadAssertion - load an Assertion from an external JSON file
  //
  // returns a promise that resolves with the contents of the assertion file

  loadAssertion: function(afile) {
    'use strict';
    if (typeof(afile) === 'string') {
      var theFile = this._parseURI(afile);
      // it is a file reference - load it
      return new Promise(function(resolve, reject) {
        this._loadFile("GET", theFile, true)
          .then(function(data) {
            data.assertionFile = afile;
            this._assertionCache[afile] = data;
            resolve(data);
          }.bind(this))
          .catch(function(err) {
            if (typeof err === "object") {
              err.theFile = theFile;
            }
            reject(err);
          });
        }.bind(this));
      }
      else if (afile.hasOwnProperty("assertionFile")) {
      // this object is referecing an external assertion
      return new Promise(function(resolve, reject) {
        var theFile = this._parseURI(afile.assertionFile);
        this._loadFile("GET", theFile, true)
        .then(function(external) {
          // okay - we have an external object
          Object.keys(afile).forEach(function(key) {
            if (key !== 'assertionFile') {
              external[key] = afile[key];
            }
          });
          resolve(external);
        }.bind(this))
        .catch(function(err) {
          if (typeof err === "object") {
            err.theFile = theFile;
          }
          reject(err);
        });
      }.bind(this));
    } else {
      // it is already a loaded assertion - just use it
      return new Promise(function(resolve) {
        resolve(afile);
      });
    }
  },

  // loadDefinition - load a JSON Schema definition from an external JSON file
  //
  // returns a promise that resolves with the contents of the definition file

  loadDefinition: function(dfile) {
    'use strict';
    return new Promise(function(resolve, reject) {
      this._loadFile("GET", this._parseURI(dfile), true)
        .then(function(data) {
          resolve(data);
        }.bind(this))
        .catch(function(err) {
          reject(err);
        });
      }.bind(this));
  },


  // loadTest - load a test from an external JSON file
  //
  // returns a promise that resolves with the contents of the
  // test

  loadTest: function(params) {
    'use strict';

    if (params.hasOwnProperty('testFile')) {
      // the test is referred to by a file name
      return this._loadFile("GET", params.testFile);
    } // else
    return new Promise(function(resolve, reject) {
      if (params.hasOwnProperty('test')) {
        resolve(params.test);
      } else {
        reject("Must supply a 'test' or 'testFile' parameter");
      }
    });
  },

  _parseURI: function(theURI) {
    'use strict';
    // determine what the top level URI should be
    if (theURI.indexOf('/') === -1) {
      // no slash - it's relative to where we are
      // so just use it
      return this.TestDir + theURI;
    } else if (theURI.indexOf('/') === 0 || theURI.indexOf('http:') === 0 || theURI.indexOf('https:') === 0) {
      // it is an absolute URI so just use it
      return theURI;
    } else {
      // it is relative and contains a slash.
      // make it relative to the current test root
      return this.Base + theURI;
    }
  },

  /**
   * return a list of all inline assertions or references
   *
   * @param {array} assertions list of assertions to examine
   */

  _assertionRefs: function(assertions) {
    'use strict';
    var ret = [] ;

    // when the reference is to an object that has an array of assertions in it (a conditionObject)
    // then remember that one and loop over its embedded assertions
    if (typeof(assertions) === "object" && !Array.isArray(assertions) && assertions.hasOwnProperty('assertions')) {
      ret.push(assertions) ;
      assertions = assertions.assertions;
    }
    if (typeof(assertions) === "object" && Array.isArray(assertions)) {
      assertions.forEach( function(assert) {
        // first - what is the type of the assert
        if (typeof assert === "object" && Array.isArray(assert)) {
          // it is a nested list - recurse
          this._assertionRefs(assert).forEach( function(item) {
            ret.push(item);
          }.bind(this));
        } else if (typeof assert === "object") {
          ret.push(assert) ;
          if (assert.hasOwnProperty("assertions")) {
            // there are embedded assertions; get those too
            ret.concat(this._assertionRefs(assert.assertions));
          }
        } else {
          // it is a file name
          ret.push(assert) ;
        }
      }.bind(this));
    }
    return ret;
  },

  // _loadFile - return a promise loading a file
  //
  _loadFile: function(method, url, parse) {
    'use strict';
    if (parse === undefined) {
      parse = true;
    }

    return new Promise(function (resolve, reject) {
      if (document.location.search) {
        var s = document.location.search;
        s = s.replace(/^\?/, '');
        if (url.indexOf('?') !== -1) {
          url += "&" + s;
        } else {
          url += "?" + s;
        }
      }
      var xhr = new XMLHttpRequest();
      xhr.open(method, url);
      xhr.onload = function () {
        if (this.status >= 200 && this.status < 300) {
          var d = xhr.response;
          if (parse) {
            try {
              d = JSON.parse(d);
              resolve(d);
            }
            catch(err) {
              reject({ status: this.status,
                       statusText: "Parsing of " + url + " failed: " + err }
                   );
            }
          } else {
            resolve(d);
          }
        } else {
          reject({
            status: this.status,
            statusText: xhr.statusText
          });
        }
      };
      xhr.onerror = function () {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      };
      xhr.send();
    });
  },

};
