// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This is intended for permanent JS behavior changes for mocking out
// non-deterministic behavior. For temporary suppressions, please refer to
// v8_suppressions.js.
// This file is loaded before each correctness test cases and won't get
// minimized.


// This will be overridden in the test cases. The override can be minimized.
var prettyPrinted = function prettyPrinted(msg) { return msg; };

// Mock Math.random.
(function() {
  let index = 1;
  Math.random = function() {
      const x = Math.sin(index++) * 10000;
      return x - Math.floor(x);
  }
})();

// Mock Math.pow. Work around an optimization for -0.5.
(function() {
  const origMathPow = Math.pow;
  Math.pow = function(a, b) {
    if (b === -0.5) {
      return 0;
    } else {
      return origMathPow(a, b);
    }
  }
})();


// Mock Date.
(function() {
  let index = 0;
  let mockDate = 1477662728696;
  const mockDateNow = function() {
    index = (index + 1) % 10;
    mockDate = mockDate + index + 1;
    return mockDate;
  }

  const origDate = Date;
  const construct = Reflect.construct;
  const constructDate = function(args) {
    let result;
    if (args.length) {
      result = construct(origDate, args);
    } else {
      result = new origDate(mockDateNow());
    }
    result.constructor = function(...args) { return constructDate(args); }
    Object.defineProperty(
        result, "constructor", { configurable: false, writable: false });
    return result;
  }

  origDate.prototype.constructor = function(...args) {
    return constructDate(args);
  };

  var handler = {
    apply: function(target, thisArg, args) {
      return constructDate(args);
    },
    construct: function(target, args, newTarget) {
      return constructDate(args);
    },
    get: function(target, property, receiver) {
      if (property == "now") {
        return mockDateNow;
      }
      if (property == "prototype") {
        return origDate.prototype;
      }
    },
  }

  Date = new Proxy(Date, handler);
})();

// Mock performance methods.
performance.now = function() { return 1.2; };
performance.measureMemory = function() { return []; };

// Mock readline so that test cases don't hang.
readline = function() { return "foo"; };

// Mock stack traces.
Error.prepareStackTrace = function(error, structuredStackTrace) {
  return "";
};
Object.defineProperty(
    Error, 'prepareStackTrace', { configurable: false, writable: false });

// Mock buffer access in float typed arrays because of varying NaN patterns.
(function() {
  const origIsNaN = isNaN;
  const deNaNify = function(value) { return origIsNaN(value) ? 1 : value; };
  const mock = function(type) {

    // Remove NaN values from parameters to "set" function.
    const set = type.prototype.set;
    type.prototype.set = function(array, offset) {
      if (Array.isArray(array)) {
        array = array.map(deNaNify);
      }
      set.apply(this, [array, offset]);
    };

    const handler = {
      // Remove NaN values from parameters to constructor.
      construct: function(target, args) {
        for (let i = 0; i < args.length; i++) {
          if (args[i] != null &&
              typeof args[i][Symbol.iterator] === 'function') {
            // Consume iterators.
            args[i] = Array.from(args[i]);
          }
          if (Array.isArray(args[i])) {
            args[i] = args[i].map(deNaNify);
          }
        }

        const obj = new (
            Function.prototype.bind.call(type, null, ...args));
        return new Proxy(obj, {
          get: function(x, prop) {
            if (typeof x[prop] == "function")
              return x[prop].bind(obj);
            return x[prop];
          },
          // Remove NaN values that get assigned.
          set: function(target, prop, value, receiver) {
            target[prop] = deNaNify(value);
            return value;
          }
        });
      },
    };
    return new Proxy(type, handler);
  }

  Float32Array = mock(Float32Array);
  Float64Array = mock(Float64Array);
})();

// Mock buffer access via DataViews because of varying NaN patterns.
(function() {
  const origIsNaN = isNaN;
  const deNaNify = function(value) { return origIsNaN(value) ? 1 : value; };
  const origSetFloat32 = DataView.prototype.setFloat32;
  DataView.prototype.setFloat32 = function(offset, value, ...rest) {
    origSetFloat32.call(this, offset, deNaNify(value), ...rest);
  };
  const origSetFloat64 = DataView.prototype.setFloat64;
  DataView.prototype.setFloat64 = function(offset, value, ...rest) {
    origSetFloat64.call(this, offset, deNaNify(value), ...rest);
  };
})();

// Mock Worker.
(function() {
  let index = 0;
  // TODO(machenbach): Randomize this for each test case, but keep stable
  // during comparison. Also data and random above.
  const workerMessages = [
    undefined, 0, -1, "", "foo", 42, [], {}, [0], {"x": 0}
  ];
  Worker = function(code){
    try {
      print(prettyPrinted(eval(code)));
    } catch(e) {
      print(prettyPrinted(e));
    }
    this.getMessage = function(){
      index = (index + 1) % 10;
      return workerMessages[index];
    }
    this.postMessage = function(msg){
      print(prettyPrinted(msg));
    }
  };
})();

// Mock Realm.
Realm.eval = function(realm, code) { return eval(code) };

// Mock the nondeterministic parts of WeakRef and FinalizationRegistry.
WeakRef.prototype.deref = function() { };
FinalizationRegistry = function(callback) { };
FinalizationRegistry.prototype.register = function(target, holdings) { };
FinalizationRegistry.prototype.unregister = function(unregisterToken) { };
FinalizationRegistry.prototype.cleanupSome = function() { };
FinalizationRegistry.prototype[Symbol.toStringTag] = "FinalizationRegistry";
