// Shell integration.
if (typeof console === 'undefined') {
  console = { log: print };
}
var tempRet0;
var binary;
if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) {
  var args = process.argv.slice(2);
  binary = require('fs').readFileSync(args[0]);
  if (!binary.buffer) binary = new Uint8Array(binary);
} else {
  var args;
  if (typeof scriptArgs != 'undefined') {
    args = scriptArgs;
  } else if (typeof arguments != 'undefined') {
    args = arguments;
  }
  if (typeof readbuffer === 'function') {
    binary = new Uint8Array(readbuffer(args[0]));
  } else {
    binary = read(args[0], 'binary');
  }
}

// Utilities.
function assert(x, y) {
  if (!x) throw (y || 'assertion failed');// + new Error().stack;
}

// Deterministic randomness.
var detrand = (function() {
  var hash = 5381; // TODO DET_RAND_SEED;
  var x = 0;
  return function() {
    hash = (((hash << 5) + hash) ^ (x & 0xff)) >>> 0;
    x = (x + 1) % 256;
    return (hash % 256) / 256;
  };
})();

// Asyncify integration.
var Asyncify = {
  sleeping: false,
  sleepingFunction: null,
  sleeps: 0,
  maxDepth: 0,
  DATA_ADDR: 4,
  DATA_MAX: 65536,
  savedMemory: null,
  instrumentImports: function(imports) {
    var ret = {};
    for (var module in imports) {
      ret[module] = {};
      for (var i in imports[module]) {
        if (typeof imports[module][i] === 'function') {
          (function(module, i) {
            ret[module][i] = function() {
              refreshView();
              if (!Asyncify.sleeping) {
                // Sleep if asyncify support is present (which also requires
                // that the memory be exported), and at a certain probability.
                if (exports.asyncify_start_unwind &&
                    view &&
                    detrand() < 0.5) {
                  // We are called in order to start a sleep/unwind.
                  console.log('asyncify: sleep in ' + i + '...');
                  Asyncify.sleepingFunction = i;
                  Asyncify.sleeps++;
                  var depth = new Error().stack.split('\n').length - 6;
                  Asyncify.maxDepth = Math.max(Asyncify.maxDepth, depth);
                  // Save the memory we use for data, so after we restore it later, the
                  // sleep/resume appears to have had no change to memory.
                  Asyncify.savedMemory = new Int32Array(view.subarray(Asyncify.DATA_ADDR >> 2, Asyncify.DATA_MAX >> 2));
                  // Unwinding.
                  // Fill in the data structure. The first value has the stack location,
                  // which for simplicity we can start right after the data structure itself.
                  view[Asyncify.DATA_ADDR >> 2] = Asyncify.DATA_ADDR + 8;
                  // The end of the stack will not be reached here anyhow.
                  view[Asyncify.DATA_ADDR + 4 >> 2] = Asyncify.DATA_MAX;
                  exports.asyncify_start_unwind(Asyncify.DATA_ADDR);
                  Asyncify.sleeping = true;
                } else {
                  // Don't sleep, normal execution.
                  return imports[module][i].apply(null, arguments);
                }
              } else {
                // We are called as part of a resume/rewind. Stop sleeping.
                console.log('asyncify: resume in ' + i + '...');
                assert(Asyncify.sleepingFunction === i);
                exports.asyncify_stop_rewind();
                // The stack should have been all used up, and so returned to the original state.
                assert(view[Asyncify.DATA_ADDR >> 2] == Asyncify.DATA_ADDR + 8);
                assert(view[Asyncify.DATA_ADDR + 4 >> 2] == Asyncify.DATA_MAX);
                Asyncify.sleeping = false;
                // Restore the memory to the state from before we slept.
                view.set(Asyncify.savedMemory, Asyncify.DATA_ADDR >> 2);
                return imports[module][i].apply(null, arguments);
              }
            };
          })(module, i);
        } else {
          ret[module][i] = imports[module][i];
        }
      }
    }
    // Add ignored.print, which is ignored by asyncify, and allows debugging of asyncified code.
    ret['ignored'] = { 'print': function(x, y) { console.log(x, y) } };
    return ret;
  },
  instrumentExports: function(exports) {
    var ret = {};
    for (var e in exports) {
      if (typeof exports[e] === 'function' &&
          !e.startsWith('asyncify_')) {
        (function(e) {
          ret[e] = function() {
            while (1) {
              var ret = exports[e].apply(null, arguments);
              // If we are sleeping, then the stack was unwound; rewind it.
              if (Asyncify.sleeping) {
                console.log('asyncify: stop unwind; rewind');
                assert(!ret, 'results during sleep are meaningless, just 0');
                //console.log('asyncify: after unwind', view[Asyncify.DATA_ADDR >> 2], view[Asyncify.DATA_ADDR + 4 >> 2]);
                try {
                  exports.asyncify_stop_unwind();
                  exports.asyncify_start_rewind(Asyncify.DATA_ADDR);
                } catch (e) {
                  console.log('error in unwind/rewind switch', e);
                }
                continue;
              }
              return ret;
            }
          };
        })(e);
      } else {
        ret[e] = exports[e];
      }
    }
    return ret;
  },
  check: function() {
    assert(!Asyncify.sleeping);
  },
  finish: function() {
    if (Asyncify.sleeps > 0) {
      print('asyncify:', 'sleeps:', Asyncify.sleeps, 'max depth:', Asyncify.maxDepth);
    }
  },
};

// Fuzz integration.
function logValue(x, y) {
  if (typeof y !== 'undefined') {
    console.log('[LoggingExternalInterface logging ' + x + ' ' + y + ']');
  } else {
    console.log('[LoggingExternalInterface logging ' + x + ']');
  }
}

// Set up the imports.
var imports = {
  'fuzzing-support': {
    'log-i32': logValue,
    'log-i64': logValue,
    'log-f32': logValue,
    'log-f64': logValue,
  },
  'env': {
    'setTempRet0': function(x) { tempRet0 = x },
    'getTempRet0': function() { return tempRet0 },
  },
};

imports = Asyncify.instrumentImports(imports);

// Create the wasm.
var module = new WebAssembly.Module(binary);

var instance;
try {
  instance = new WebAssembly.Instance(module, imports);
} catch (e) {
  console.log('exception: failed to instantiate module');
  quit();
}

// Handle the exports.
var exports = instance.exports;
exports = Asyncify.instrumentExports(exports);

var view;

// Recreate the view. This is important both initially and after a growth.
function refreshView() {
  if (exports.memory) {
    view = new Int32Array(exports.memory.buffer);
  }
}

// Run the wasm.
var sortedExports = [];
for (var e in exports) {
  sortedExports.push(e);
}
sortedExports.sort();
sortedExports = sortedExports.filter(function(e) {
  // Filter special intrinsic functions.
  return !e.startsWith('asyncify_');
});
sortedExports.forEach(function(e) {
  Asyncify.check();
  if (typeof exports[e] !== 'function') return;
  try {
    console.log('[fuzz-exec] calling ' + e);
    var result = exports[e]();
    if (typeof result !== 'undefined') {
      console.log('[fuzz-exec] note result: $' + e + ' => ' + result);
    }
  } catch (e) {
    console.log('exception!');// + [e, e.stack]);
  }
});

// Finish up
Asyncify.finish();
