'use strict';

var Ajv = require('./ajv')
  , util = require('../lib/compile/util');

module.exports = getAjvInstances;


var firstTime = true;

var isBrowser = typeof window == 'object';
var fullTest = isBrowser || !process.env.AJV_FAST_TEST;


function getAjvInstances(opts) {
  opts = opts || {};
  var instances = [];
  var options = [
    {},
    { async: true },
    { async: 'co*' },
    { async: 'es7' },
    { async: 'es7', transpile: 'nodent' },
    { async: '*', transpile: 'regenerator' },
    { async: 'co*', allErrors: true },
    { async: 'es7', allErrors: true },
    { async: 'es7', transpile: 'nodent', allErrors: true },
    { async: '*', transpile: 'regenerator', allErrors: true }
  ];

  if (fullTest) options = options.concat([
    { async: '*' },
    { transpile: 'regenerator' },
    { async: true, transpile: 'regenerator' },
    { async: 'co*', transpile: 'regenerator' },
    { async: 'es7', transpile: 'regenerator' },
    { allErrors: true },
    { async: true, allErrors: true },
    { async: '*', allErrors: true },
    { transpile: 'regenerator', allErrors: true },
    { async: true, transpile: 'regenerator', allErrors: true },
    { async: 'co*', transpile: 'regenerator', allErrors: true },
    { async: 'es7', transpile: 'regenerator', allErrors: true }
  ]);

  // options = options.filter(function (_opts) {
  //   return _opts.transpile == 'nodent';
  // });

  // var i = 10, repeatOptions = [];
  // while (i--) repeatOptions = repeatOptions.concat(options);
  // options = repeatOptions;

  options.forEach(function (_opts) {
    util.copy(opts, _opts);
    var ajv = getAjv(_opts);
    if (ajv) instances.push(ajv);
  });


  if (firstTime) {
    var asyncModes = [];
    instances.forEach(function (ajv) {
      if (!ajv._opts.async) return;
      var t = ajv._opts.transpile;
      var mode = ajv._opts.async + (t === true ? '' : '.' + t);
      if (asyncModes.indexOf(mode) == -1) asyncModes.push(mode);
    });
    console.log('Testing', instances.length, 'ajv instances:', asyncModes.join(','));
    firstTime = false;
  }

  return instances;
}


function getAjv(opts){
  try { return Ajv(opts); } catch(e) {}
}

@@ -716,16 +716,22 @@
 ullTest)
+ %7B%0A   
  options
@@ -750,24 +750,26 @@
 oncat(%5B%0A    
+  
 %7B async: '*'
@@ -768,29 +768,45 @@
 ync: '*' %7D,%0A
+  
     %7B
+ async: 'co*',
  transpile: 
@@ -830,51 +830,112 @@
     
-%7B async: true, transpile: 'regenerator'
+  %7B allErrors: true %7D,%0A      %7B async: true, allErrors: true %7D,%0A      %7B async: '*', allErrors: true
  %7D,%0A
+  
     
@@ -974,39 +974,149 @@
 nerator'
+, allErrors: true
  %7D
-,
 %0A    
-%7B async: 'es7',
+%5D);%0A%0A    var ua;%0A    try %7B ua = window.navigator.userAgent.toLowerCase(); %7D catch(e) %7B%7D%0A%0A    // es7 functions
  transpi
@@ -1109,35 +1109,39 @@
 ctions transpile
-: '
+d with 
 regenerator' %7D,%0A
@@ -1139,168 +1139,332 @@
 ator
-' %7D,%0A    %7B allErrors: true %7D,%0A    %7B async: true, allErrors: true %7D,%0A    %7B async: '*', allErrors: true %7D,%0A    %7B transpile: 'regenerator', allErrors: true
+ are excluded from test in Safari.%0A    // They emit multiple 'uncaught exception' warnings in Safari anc cause remote tests to disconnect.%0A    if (ua && (!/safari/.test(ua) %7C%7C /chrome/.test(ua))) %7B%0A      options = options.concat(%5B%0A        %7B transpile: 'regenerator' %7D,%0A        %7B async: true, transpile: 'regenerator'
  %7D,%0A    
 %7B as
@@ -1451,32 +1451,36 @@
 nerator' %7D,%0A    
+ 
+   
 %7B async: true, t
@@ -1464,37 +1464,76 @@
        %7B async: 
-true,
+'es7', transpile: 'regenerator' %7D,%0A        %7B
  transpile: 'reg
@@ -1554,32 +1554,36 @@
 Errors: true %7D,%0A
+    
     %7B async: 'co
@@ -1571,37 +1571,36 @@
        %7B async: 
-'co*'
+true
 , transpile: 're
@@ -1622,32 +1622,36 @@
 Errors: true %7D,%0A
+    
     %7B async: 'es
@@ -1700,19 +1700,33 @@
 rue %7D%0A  
-%5D);
+    %5D);%0A    %7D%0A  %7D
 %0A%0A  // o

exclude es7.regenerator async test when running in Safari