// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Random-walk fuzzer for the Dart VM.
//
// Start with all the classes and libraries and various interesting values.
// Repeatedly choose one as a receiver, construct a message it is likely to
// understand, send the message, and add the result.
//
// Intentionally not run on the build bots because through dart:io it could
// trash their setups.

library fuzzer;

import 'dart:io';
import 'dart:math';
import 'dart:mirrors';
import 'dart:typed_data';

var excludeList = [
  'dart.io.exit',
  'dart.io.exitCode',
  'dart.io.sleep',
  'dart.io.Process.killPid',
];

final bool trace = false;

void main(List<String> args) {
  int seed;
  if (args.length == 1) {
    seed = int.parse(args[0]);
  } else {
    // Dart's built-in random number generator doesn't provide access to the
    // seed when it is chosen by the implementation. We need to be able to
    // report this seed to make runs of the fuzzer reproducible, so we create
    // the seed ourselves.

    // When running on many machines in parallel, the current time alone
    // is a poor choice of seed.
    seed = 0;
    try {
      var f = new File("/dev/urandom").openSync();
      seed = (seed << 8) | f.readByteSync();
      seed = (seed << 8) | f.readByteSync();
      seed = (seed << 8) | f.readByteSync();
      seed = (seed << 8) | f.readByteSync();
      f.close();
    } catch (e) {
      print("Failed to read from /dev/urandom: $e");
    }

    seed ^= new DateTime.now().millisecondsSinceEpoch;
    seed &= 0xFFFFFFFF;
  }
  random = new Random(seed);

  // Information needed to reproduce this run.
  print("Dart VM fuzzer");
  print("Executable: ${Platform.executable}");
  print("Arguments: ${Platform.executableArguments}");
  print("Version: ${Platform.version}");
  print("Seed: ${seed}");
  print("------------------------------------------");

  setupInterestingValues();
  setupClasses();

  // Bound the number of steps in our random walk so that if any issue is found
  // it can be reproduced without having to wait too long.
  for (int i = 0; i < 100000; i++) {
    fuzz(randomElementOf(candidateReceivers));
    if (maybe(0.01)) garbageCollect();
  }
}

Random random;

bool maybe(probability) => random.nextDouble() < probability;

randomElementOf(list) {
  return list.length == 0 ? null : list[random.nextInt(list.length)];
}

class Candidate<T> {
  Candidate origin;
  String message;
  T mirror;
  trace() {
    if (origin == null) {
      print("");
    } else {
      origin.trace();
      print(" $message");
    }
    print(mirror);
  }
}

List<Candidate<ObjectMirror>> candidateReceivers = <Candidate<ObjectMirror>>[];
List<Candidate<InstanceMirror>> candidateArguments =
    <Candidate<InstanceMirror>>[];

void addInstance(var instance) {
  addInstanceMirror(reflect(instance));
}

void addInstanceMirror(
  InstanceMirror mirror, [
  Candidate origin,
  String message,
]) {
  var c = new Candidate<InstanceMirror>();
  c.mirror = mirror;
  c.origin = origin;
  c.message = message;

  candidateReceivers.add(c);
  candidateArguments.add(c);
}

void addObjectMirror(ObjectMirror mirror) {
  var c = new Candidate<ObjectMirror>();
  c.mirror = mirror;
  c.origin = null;
  c.message = null;

  candidateReceivers.add(c);
}

void setupInterestingValues() {
  addInstance(null);
  addInstance(true);
  addInstance(false);

  addInstance([]);
  addInstance(const []);
  addInstance({});
  addInstance(const {});

  addInstance(() => null);

  addInstance(-1);
  addInstance(0);
  addInstance(1);
  addInstance(2);

  addInstance(1 << 31);
  addInstance(1 << 31 + 1);
  addInstance(1 << 31 - 1);

  addInstance(1 << 32);
  addInstance(1 << 32 + 1);
  addInstance(1 << 32 - 1);

  addInstance(1 << 63);
  addInstance(1 << 63 + 1);
  addInstance(1 << 63 - 1);

  addInstance(1 << 64);
  addInstance(1 << 64 + 1);
  addInstance(1 << 64 - 1);

  addInstance(-1.0);
  addInstance(0.0);
  addInstance(1.0);
  addInstance(2.0);
  addInstance(double.nan);
  addInstance(double.infinity);
  addInstance(double.negativeInfinity);
  addInstance(double.minPositive);
  addInstance(double.maxFinite);

  addInstance("foo"); // ASCII string
  addInstance("blåbærgrød"); // Latin1 string
  addInstance("Îñţérñåţîöñåļîžåţîờñ"); // Unicode string
  addInstance("𝄞"); // Surrogate pairs
  addInstance("𝄞"[0]); // Surrogate pairs
  addInstance("𝄞"[1]); // Surrogate pairs
  addInstance("\u{0}"); // Non-printing character
  addInstance("\u{1}"); // Non-printing character
  addInstance("f\u{0}oo"); // Internal NUL
  addInstance("blåbæ\u{0}rgrød"); // Internal NUL
  addInstance("Îñţérñåţîö\u{0}ñåļîžåţîờñ"); // Internal NUL
  addInstance("\u{0}𝄞"); // Internal NUL

  for (int len = 0; len < 8; len++) {
    addInstance(fillInt(new Int8List(len)));
    addInstance(fillInt(new Int16List(len)));
    addInstance(fillInt(new Int32List(len)));
    addInstance(fillInt(new Int64List(len)));
    addInstance(fillInt(new Uint8List(len)));
    addInstance(fillInt(new Uint16List(len)));
    addInstance(fillInt(new Uint32List(len)));
    addInstance(fillInt(new Uint64List(len)));
    addInstance(fillFloat(new Float32List(len)));
    addInstance(fillFloat(new Float64List(len)));
  }

  randomInstance(ignore) {
    return randomElementOf(candidateArguments).mirror.reflectee;
  }

  for (int len = 0; len < 8; len++) {
    addInstance(new List.generate(len, randomInstance));
  }
}

void fillInt(TypedData d) {
  for (var i = 0; i < d.length; i++) {
    d[i] = random.nextInt(0xFFFFFFFF);
  }
}

void fillFloat(TypedData d) {
  for (var i = 0; i < d.length; i++) {
    d[i] = random.nextDouble();
  }
}

void setupClasses() {
  currentMirrorSystem().libraries.values.forEach((lib) {
    if (lib.simpleName == #fuzzer) return; // Don't recurse.
    addObjectMirror(lib);
    lib.declarations.values.forEach((decl) {
      if (decl is ClassMirror) {
        addObjectMirror(decl);
      }
    });
  });
}

MethodMirror randomMethodOf(receiver) {
  if (receiver is ClassMirror) {
    return randomElementOf(
      receiver.declarations.values
          .where((d) => d is MethodMirror && d.isStatic)
          .toList(),
    );
  } else if (receiver is LibraryMirror) {
    return randomElementOf(
      receiver.declarations.values.where((d) => d is MethodMirror).toList(),
    );
  } else if (receiver is InstanceMirror) {
    var methods = [];
    var cls = receiver.type;
    while (cls != reflectClass(Object)) {
      cls.declarations.values.forEach((d) {
        if (d is MethodMirror && !d.isStatic) methods.add(d);
      });
      cls = cls.superclass;
    }
    return randomElementOf(methods);
  }
  throw new Error("UNREACHABLE");
}

String prettyMessageName(receiver, method) {
  var r = "?", m = "?";
  if (receiver is InstanceMirror) {
    r = MirrorSystem.getName(receiver.type.simpleName);
  } else if (receiver is ClassMirror) {
    r = MirrorSystem.getName(receiver.simpleName);
    r = "$r class";
  } else if (receiver is LibraryMirror) {
    r = MirrorSystem.getName(receiver.simpleName);
    r = "$r lib";
  }
  m = MirrorSystem.getName(method.simpleName);
  return "$r>>#$m";
}

void fuzz(Candidate c) {
  ObjectMirror receiver = c.mirror;
  MethodMirror method = randomMethodOf(receiver);
  if (method == null) return;
  if (excludeList.contains(MirrorSystem.getName(method.qualifiedName))) return;

  List positional = randomPositionalArgumentsFor(method);
  Map named = randomNamedArgumentsFor(method);
  InstanceMirror result;

  String message = prettyMessageName(receiver, method);
  if (trace) {
    c.trace();
    print(message);
  }

  if (method.isConstructor) {
    try {
      result = receiver.newInstance(method.simpleName, positional, named);
    } catch (e) {}
  } else if (method.isRegularMethod) {
    try {
      result = receiver.invoke(method.simpleName, positional, named);
    } catch (e) {}
  } else if (method.isGetter) {
    try {
      result = receiver.getField(method.simpleName);
    } catch (e) {}
  } else if (method.isSetter) {
    try {
      result = receiver.setField(method.simpleName, positional[0]);
    } catch (e) {}
  }

  if (result != null) {
    addInstanceMirror(result, c, message);
  }
}

InstanceMirror randomArgumentWithBias(TypeMirror bias) {
  if (maybe(0.75)) {
    for (var candidate in candidateArguments) {
      if (candidate.mirror.type.isAssignableTo(bias)) {
        return candidate.mirror;
      }
    }
  }
  return randomElementOf(candidateArguments).mirror;
}

List randomPositionalArgumentsFor(MethodMirror method) {
  var result = [];
  for (int i = 0; i < method.parameters.length; i++) {
    ParameterMirror p = method.parameters[i];
    if (!p.isNamed && (!p.isOptional || maybe(0.5))) {
      result.add(randomArgumentWithBias(p.type));
    }
  }
  return result;
}

Map randomNamedArgumentsFor(MethodMirror method) {
  var result = {};
  for (int i = 0; i < method.parameters.length; i++) {
    ParameterMirror p = method.parameters[i];
    if (p.isNamed && maybe(0.5)) {
      result[p.simpleName] = randomArgumentWithBias(p.type);
    }
  }

  return result;
}

void garbageCollect() {
  // Chain a bunch of moderately sized arrays, then let go of them. Using a
  // moderate size avoids our allocations going directly to a large object
  // page in old space.
  var n;
  for (int i = 0; i < 2048; i++) {
    var m = new List.filled(512, null);
    m[0] = n;
    n = m;
  }
}
