// Copyright (c) 2018, 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.

import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';

import 'dartfuzz_api_table.dart';
import 'dartfuzz_ffi_api.dart';
import 'dartfuzz_type_table.dart';

// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
const String version = '1.88';

// Restriction on statements and expressions.
const int stmtDepth = 1;
const int exprDepth = 2;
const int nestDepth = 1;
const int numStatements = 2;
const int numGlobalVars = 4;
const int numLocalVars = 4;
const int numGlobalMethods = 4;
const int numMethodParams = 4;
const int numClasses = 4;
const int numExtensionMethodsPerClass = 3;
const int numDartTypeExtensions = 5;

// Naming conventions.
const varName = 'var';
const paramName = 'par';
const localName = 'loc';
const fieldName = 'fld';
const methodName = 'foo';

/// Enum for the different types of methods generated by the fuzzer.
enum MethodType {
  globalMethod,
  ffiMethod,
  instanceMethod,
  callMethod,
  extensionMethod
}

/// Base class for all methods in the program generated by DartFuzz.
abstract class Method {
  Method(this.name, this.parameters, this.fuzzer)
      : recursionAllowed = fuzzer.coinFlip() {
    if (recursionAllowed) {
      // Add the recursion depth parameter.
      parameters.add(DartType.INT);
    }
  }

  String get recursionDepthParamName => '${paramName}${parameters.length - 1}';
  DartType get returnType => parameters[0];

  void emitCallParameters(int depth, bool isRecursiveCall,
      {RhsFilter rhsFilter}) {
    if (isRecursiveCall && !recursionAllowed) {
      throw StateError('Did not expect a recursive call in $name');
    }
    fuzzer.emitParenWrapped(() => fuzzer.emitCommaSeparated((int i) {
          // If this function can be called recursively, the last parameter is the
          // recursion depth parameter.
          if (i == parameters.length - 1 && recursionAllowed) {
            if (isRecursiveCall) {
              // This is a recursive call, so we increase the recursion depth
              // parameter.
              fuzzer.emit('$recursionDepthParamName + 1');
            } else {
              // This isn't a recursive call. Our recursion depth is 0.
              fuzzer.emit('0');
            }
          } else {
            fuzzer.emitExpr(depth, parameters[i], rhsFilter: rhsFilter);
          }
        }, parameters.length, start: 1));
  }

  void disableRecursionScope(Function callback) {
    final originalState = recursionAllowed;
    recursionAllowed = false;
    callback();
    recursionAllowed = originalState;
  }

  void emitRecursionBaseCase() {
    fuzzer.emitIfStatement(() {
      fuzzer.emit("$recursionDepthParamName >= ");
      fuzzer.emitSmallPositiveInt();
    }, () {
      // Temporarily set recursionAllowed to false so that we don't have a
      // recursive call in the return statement of the base case.
      disableRecursionScope(fuzzer.emitReturn);
      return false;
    });
  }

  void emitFunctionBody() {
    if (!recursionAllowed && fuzzer.rollDice(10)) {
      // Emit a method using "=>" syntax.
      fuzzer.emit(' => ');
      fuzzer.emitExpr(0, returnType, includeSemicolon: true);
    } else {
      fuzzer.emitBraceWrapped(() {
        assert(fuzzer.localVars.isEmpty);
        if (recursionAllowed) {
          emitRecursionBaseCase();
        }
        if (fuzzer.emitStatements(0)) {
          fuzzer.emitReturn();
        }
        assert(fuzzer.localVars.isEmpty);
      });
    }
  }

  void emitFunctionDefinition() {
    final type = returnType.name;
    fuzzer.emitLn('$type ${name}', newline: false);
    fuzzer.emitParenWrapped(() => fuzzer.emitParDecls(parameters));
    emitFunctionBody();
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  String emitCall(int depth,
      {RhsFilter rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    String outputName = name;
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  // Main emitter for a method.
  void emit() {
    emitFunctionDefinition();
  }

  final String name;
  final List<DartType> parameters;
  final DartFuzz fuzzer;
  bool recursionAllowed;
}

/// Class for global methods generated by DartFuzz.
class GlobalMethod extends Method {
  GlobalMethod(String name, List<DartType> parameters, DartFuzz fuzzer)
      : super(name, parameters, fuzzer);
}

/// Class for ffi methods generated by DartFuzz.
class FfiMethod extends Method {
  FfiMethod(
      String namePrefix, int index, List<DartType> parameters, DartFuzz fuzzer)
      : ffiCastName = "${namePrefix}FfiCast${index}",
        super("${namePrefix}Ffi${index}", parameters, fuzzer) {}

  @override
  void emitFunctionBody() {
    fuzzer.emitBraceWrapped(() {
      assert(fuzzer.localVars.isEmpty);
      if (recursionAllowed) {
        emitRecursionBaseCase();
      }
      if (fuzzer.emitStatements(0)) {
        fuzzer.emitReturn();
      }
      assert(fuzzer.localVars.isEmpty);
    });
  }

  @override
  void emit() {
    fuzzer.emitFfiTypedef(this);
    emitFunctionDefinition();
    fuzzer.emitFfiCast("${ffiCastName}", "${name}", "${name}Type", parameters);
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  final String ffiCastName;
}

/// Class for instance methods generated by DartFuzz.
class InstanceMethod extends Method {
  InstanceMethod(
      String name, List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super(name, parameters, fuzzer) {}

  @override
  String emitCall(int depth,
      {RhsFilter rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    String outputName = name;
    if (fuzzer.currentClassIndex == null) {
      // If we're calling an instance method from outside the class, then we
      // should construct an object of that class first.
      outputName = "${className}().${name}";
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
}

class CallMethod extends Method {
  CallMethod(List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super("call", parameters, fuzzer) {}

  @override
  String emitCall(int depth,
      {RhsFilter rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    String outputName;
    outputName = "${className}()";
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  @override
  void emit() {
    // Override the parent class' call method.
    fuzzer.emit("@override");
    fuzzer.emitNewline();
    emitFunctionDefinition();
  }

  final String className;
}

// Class for extension methods generated by DartFuzz.
class ExtensionMethod extends Method {
  ExtensionMethod(String name, List<DartType> parameters, DartFuzz fuzzer,
      this.className, this.extensionName, this.type)
      : super(name, parameters, fuzzer) {}
  @override
  String emitCall(
    int depth, {
    RhsFilter rhsFilter,
    bool includeSemicolon = false,
    bool isRecursiveCall = false,
  }) {
    String outputName = name;

    // If we're calling an extension method on a class from outside the class,
    // we must call it using an object of the class or using explicit extension
    // application. Extension methods on Dart types are presently always called
    // using a variable of the Dart type or using explicit extension
    // application.
    if (fuzzer.currentClassIndex == null || type != null) {
      String invokingObject =
          type != null ? fuzzer.pickScalarVar(type) : "${className}()";

      if (extensionName != null && fuzzer.coinFlip()) {
        outputName = "${extensionName}(${invokingObject}).${name}";
      } else {
        outputName = "${invokingObject}.${name}";
      }
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
  final String extensionName;
  final DartType type;
}

// Class that tracks the state of the filter applied to the
// right-hand-side of an assignment in order to avoid generating
// left-hand-side variables.
class RhsFilter {
  RhsFilter(this._remaining, this.lhsVar);
  factory RhsFilter.fromDartType(DartType tp, String lhsVar) {
    if (DartType.isGrowableType(tp)) {
      return RhsFilter(1, lhsVar);
    }
    return null;
  }
  // Clone the current RhsFilter instance and set remaining to 0.
  // This is used for parameter expressions.
  factory RhsFilter.cloneEmpty(RhsFilter rhsFilter) =>
      rhsFilter == null ? null : RhsFilter(0, rhsFilter.lhsVar);
  void consume() => _remaining--;
  bool get shouldFilter => _remaining <= 0;
  // Number of times the lhs variable can still be used on the rhs.
  int _remaining;
  // The name of the lhs variable to be filtered from the rhs.
  final String lhsVar;
}

/// Class that specifies the api for calling library and ffi functions (if
/// enabled).
class DartApi {
  DartApi(bool ffi) : typeToLibraryMethods = DartLib.typeToLibraryMethods {
    if (ffi) {
      typeToLibraryMethods[DartType.INT] = [
        ...[
          DartLib('intComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('takeMaxUint16', [DartType.VOID, DartType.INT], true),
          DartLib(
              'sumPlus42', [DartType.VOID, DartType.INT, DartType.INT], true),
          DartLib('returnMaxUint8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint32', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt32', [DartType.VOID, DartType.VOID], true),
          DartLib('takeMinInt16', [DartType.VOID, DartType.INT], true),
          DartLib('takeMinInt32', [DartType.VOID, DartType.INT], true),
          DartLib('uintComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('sumSmallNumbers',
              [DartType.VOID, ...List<DartType>.filled(6, DartType.INT)], true),
          DartLib('takeMinInt8', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint32', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint8', [DartType.VOID, DartType.INT], true),
          DartLib('minInt64', [DartType.VOID, DartType.VOID], true),
          DartLib('minInt32', [DartType.VOID, DartType.VOID], true),
          // Use small int to avoid overflow divergences due to size
          // differences in intptr_t on 32-bit and 64-bit platforms.
          DartLib('sumManyIntsOdd',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
          DartLib('sumManyInts',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(10, Restriction.small)
              ]),
          DartLib('regress37069',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
        ],
        ...DartLib.intLibs,
      ];

      typeToLibraryMethods[DartType.DOUBLE] = [
        if (ffi) ...[
          DartLib('times1_337Float', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyDoubles',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.DOUBLE)],
              true),
          DartLib('times1_337Double', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyNumbers',
              [
                DartType.VOID,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE
              ],
              true),
          DartLib('inventFloatValue', [DartType.VOID, DartType.VOID], true),
          DartLib('smallDouble', [DartType.VOID, DartType.VOID], true),
        ],
        ...DartLib.doubleLibs,
      ];
    }
  }

  final typeToLibraryMethods;
}

/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
  DartFuzz(this.seed, this.fp, this.ffi, this.flatTp, this.file,
      {this.minimize = false, this.smask, this.emask});

  void run() {
    // Initialize program variables.
    rand = Random(seed);
    indent = 0;
    nest = 0;
    currentClassIndex = null;
    currentMethod = null;
    currentMethodIndex = null;
    // Setup Dart types.
    dartType = DartType.fromDartConfig(enableFp: fp, disableNesting: flatTp);
    // Setup minimization parameters.
    initMinimization();
    // Setup the library and ffi api.
    api = DartApi(ffi);
    // Setup the types.
    localVars = <DartType>[];
    iterVars = <String>[];
    globalVars = fillTypes1(limit: numGlobalVars);
    globalVars.addAll(dartType.allTypes);
    globalMethods = getMethods(
        numGlobalMethods, numMethodParams, MethodType.globalMethod,
        namePrefix: methodName);
    classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
    final int numClassMethods = 1 + numClasses - classFields.length;
    classMethods = getClassMethods(classFields.length, numClassMethods,
        numMethodParams, fillTypes1(limit: numMethodParams));
    virtualClassMethods = <Map<int, List<int>>>[];
    classParents = <int>[];
    // Setup optional ffi methods and types.
    if (ffi) {
      globalMethods.addAll(getMethods(
          numGlobalMethods, numMethodParams, MethodType.ffiMethod,
          namePrefix: methodName));
    }
    // Generate.
    emitHeader();
    emitVariableDeclarations(varName, globalVars);
    emitMethods(globalMethods);
    for (int i = 0; i < numDartTypeExtensions; ++i) {
      DartType type = oneOfSet(dartType.allTypes);
      emitAndAddExtensionMethods(globalMethods, type.name, "${methodName}E${i}",
          "${methodName}${i}_Extension",
          type: type);
    }
    emitClasses();
    emitMain();
    // Sanity.
    assert(currentClassIndex == null);
    assert(currentMethod == null);
    assert(currentMethodIndex == null);
    assert(indent == 0);
    assert(nest == 0);
    assert(localVars.isEmpty);
  }

  List<Method> getMethods(int maxMethods, int maxParams, MethodType methodType,
      {String className,
      String extensionName,
      String namePrefix,
      DartType type}) {
    final List<Method> list = <Method>[];
    for (int i = 0, n = chooseOneUpTo(maxMethods); i < n; i++) {
      final List<DartType> params = fillTypes1(
          limit: maxParams, isFfi: methodType == MethodType.ffiMethod);
      switch (methodType) {
        case MethodType.globalMethod:
          list.add(GlobalMethod("${namePrefix}${i}", params, this));
          break;
        case MethodType.ffiMethod:
          list.add(FfiMethod(namePrefix, i, params, this));
          break;
        case MethodType.instanceMethod:
          list.add(
              InstanceMethod("${namePrefix}${i}", params, this, className));
          break;
        case MethodType.extensionMethod:
          list.add(ExtensionMethod("${namePrefix}${i}", params, this, className,
              extensionName, type));
          break;
        default:
          break;
      }
    }
    return list;
  }

  List<List<Method>> getClassMethods(int numClasses, int maxMethods,
      int maxParams, List<DartType> callMethodParams) {
    final methodsForAllClasses = <List<Method>>[];
    for (int i = 0; i < numClasses; i++) {
      final methodsForCurrentClass = getMethods(
          maxMethods, maxParams, MethodType.instanceMethod,
          className: "X${i}", namePrefix: "${methodName}${i}_");
      // Add the call method for the current class. The prototype for the call
      // method is pre-decided. This is because we are possibly overriding the
      // parent class' call method, in which case the prototype should be the
      // same. To simplify the dartfuzz logic, all call methods have the same
      // prototype.
      methodsForCurrentClass.add(CallMethod(callMethodParams, this, "X${i}"));
      methodsForAllClasses.add(methodsForCurrentClass);
    }
    return methodsForAllClasses;
  }

  //
  // General Helpers.
  //

  BigInt genMask(int m) => BigInt.from(1) << m;
  int choose(int c) => rand.nextInt(c);
  int chooseOneUpTo(int c) => choose(c) + 1;
  bool coinFlip() => rand.nextBool();
  bool rollDice(int c) => (choose(c) == 0);
  double uniform() => rand.nextDouble();

  // Picks one of the given choices.
  T oneOf<T>(List<T> choices) => choices[choose(choices.length)];
  T oneOfSet<T>(Set<T> choices) => choices.elementAt(choose(choices.length));

  //
  // Code Structure Helpers.
  //

  void incIndent() => indent += 2;
  void decIndent() => indent -= 2;

  void emitZero() => emit('0');

  void emitTryCatchFinally(Function tryBody, Function catchBody,
      {Function finallyBody}) {
    emitLn('try ', newline: false);
    emitBraceWrapped(() => tryBody());
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn("exit(${oomExitCode});", newline: false));
    emit(' catch (e, st) ');
    emitBraceWrapped(catchBody);
    if (finallyBody != null) {
      emit(' finally ');
      emitBraceWrapped(finallyBody);
    }
  }

  dynamic emitWrapped(List<String> pair, Function exprEmitter,
      {bool shouldIndent = true}) {
    assert(pair.length == 2);
    emit(pair[0]);
    if (shouldIndent) {
      incIndent();
      emitNewline();
    }
    final result = exprEmitter();
    if (shouldIndent) {
      decIndent();
      emitNewline();
      emitLn(pair[1], newline: false);
    } else {
      emit(pair[1]);
    }
    return result;
  }

  dynamic emitParenWrapped(Function exprEmitter,
      {bool includeSemicolon = false}) {
    final result =
        emitWrapped(const ['(', ')'], exprEmitter, shouldIndent: false);
    if (includeSemicolon) {
      emit(';');
    }
    return result;
  }

  dynamic emitBraceWrapped(Function exprEmitter, {bool shouldIndent = true}) =>
      emitWrapped(const ['{', '}'], exprEmitter, shouldIndent: shouldIndent);

  dynamic emitSquareBraceWrapped(Function exprEmitter) =>
      emitWrapped(const ['[', ']'], exprEmitter, shouldIndent: false);

  dynamic emitCommaSeparated(Function(int) elementBuilder, int length,
      {int start = 0, bool newline = false}) {
    for (int i = start; i < length; ++i) {
      elementBuilder(i);
      if (i + 1 != length) {
        emit(',', newline: newline);
        if (!newline) {
          emit(' ');
        }
      }
    }
  }

  void emitFunctionDefinition(String name, Function body, {String retType}) {
    emitIndentation();
    if (retType != null) {
      emit(retType + ' ');
    }
    emit(name);
    emit('() '); // TODO(bkonyi): handle params

    emitBraceWrapped(body);
  }

  bool emitIfStatement(
      Function ifConditionEmitter, bool Function() ifBodyEmitter,
      {bool Function() elseBodyEmitter}) {
    emitLn('if ', newline: false);
    emitParenWrapped(ifConditionEmitter);
    emit(' ');
    final bool b1 = emitBraceWrapped(ifBodyEmitter);
    bool b2 = false;
    if (elseBodyEmitter != null) {
      emit(' else ');
      b2 = emitBraceWrapped(elseBodyEmitter);
    }
    return b1 || b2;
  }

  void emitImport(String library, {String asName}) => (asName == null)
      ? emitLn("import '$library';")
      : emitLn("import '$library' as $asName;");

  void emitBinaryComparison(Function e1, String op, Function e2,
      {bool includeSemicolon = false}) {
    e1();
    emit(' $op ');
    e2();
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Randomly specialize interface if possible. E.g. num to int.
  DartType maybeSpecializeInterface(DartType tp) {
    if (!dartType.isSpecializable(tp)) return tp;
    DartType resolvedTp = oneOfSet(dartType.interfaces(tp));
    return resolvedTp;
  }

  //
  // Minimization components.
  //

  void initMinimization() {
    stmtCntr = 0;
    exprCntr = 0;
    skipStmt = false;
    skipExpr = false;
  }

  void emitMinimizedLiteral(DartType tp) {
    switch (tp) {
      case DartType.BOOL:
        emit('true');
        break;
      case DartType.INT:
        emit('1');
        break;
      case DartType.DOUBLE:
        emit('1.0');
        break;
      case DartType.STRING:
        emit('"a"');
        break;
      case DartType.LIST_INT:
        emit('[1]');
        break;
      case DartType.SET_INT:
        emit('{1}');
        break;
      case DartType.MAP_INT_STRING:
        emit('{1: "a"}');
        break;
      default:
        throw 'Unknown DartType ${tp}';
    }
  }

  // Process the opening of a statement.
  // Determine whether the statement should be skipped based on the
  // statement index stored in stmtCntr and the statement mask stored
  // in smask.
  // Returns true if the statement should be skipped.
  bool processStmtOpen() {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current statement number is set in the
    // statement bitmap. If so skip this statement.
    final newMask = genMask(stmtCntr);
    final maskBitSet = (smask & newMask) != BigInt.zero;
    // Statements are nested, therefore masking one statement like e.g.
    // a for loop leads to other statements being omitted.
    // Here we update the statement mask to include the additionally
    // omitted statements.
    if (skipStmt) {
      smask |= newMask;
    }
    // Increase the statement counter.
    stmtCntr++;
    if (!skipStmt && maskBitSet) {
      skipStmt = true;
      return true;
    }
    return false;
  }

  // Process the closing of a statement.
  // The variable resetSkipStmt indicates whether this
  // statement closes the sequence of skipped statement.
  // E.g. the end of a loop where all contained statements
  // were skipped.
  void processStmtClose(bool resetSkipStmt) {
    if (!minimize) {
      return;
    }
    if (resetSkipStmt) {
      skipStmt = false;
    }
  }

  // Process the opening of an expression.
  // Determine whether the expression should be skipped based on the
  // expression index stored in exprCntr and the expression mask stored
  // in emask.
  // Returns true is the expression is skipped.
  bool processExprOpen(DartType tp) {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current expression number is set in the
    // expression bitmap. If so skip this expression.
    final newMask = genMask(exprCntr);
    final maskBitSet = (emask & newMask) != BigInt.zero;
    // Expressions are nested, therefore masking one expression like e.g.
    // a for loop leads to other expressions being omitted.
    // Similarly, if the whole statement is skipped, all the expressions
    // within that statement are implicitly masked.
    // Here we update the expression mask to include the additionally
    // omitted expressions.
    if (skipExpr || skipStmt) {
      emask |= newMask;
    }
    exprCntr++;
    if (skipStmt) {
      return false;
    }
    if (!skipExpr && maskBitSet) {
      emitMinimizedLiteral(tp);
      skipExpr = true;
      return true;
    }
    return false;
  }

  void processExprClose(bool resetExprStmt) {
    if (!minimize || skipStmt) {
      return;
    }
    if (resetExprStmt) {
      skipExpr = false;
    }
  }

  //
  // Program components.
  //

  void emitHeader() {
    emitLn('// The Dart Project Fuzz Tester ($version).');
    emitLn('// Program generated as:');
    emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
        '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
    emitNewline();
    emitImport('dart:async');
    emitImport('dart:cli');
    emitImport('dart:collection');
    emitImport('dart:convert');
    emitImport('dart:core');
    emitImport('dart:io');
    emitImport('dart:isolate');
    emitImport('dart:math');
    emitImport('dart:typed_data');
    if (ffi) {
      emitImport('dart:ffi', asName: 'ffi');
      emitLn(DartFuzzFfiApi.ffiapi);
    }
    emitNewline();
  }

  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
      List<DartType> pars) {
    emit("${pars[0].name} Function");
    emitParenWrapped(() => emitCommaSeparated(
        (int i) => emit('${pars[i].name}'), pars.length,
        start: 1));
    emit(' ${dartFuncName} = ffi.Pointer.fromFunction<${typeName}>');
    emitParenWrapped(() {
      emit('${ffiFuncName}, ');
      emitLiteral(0, pars[0], smallPositiveValue: true);
    });
    emit('.cast<ffi.NativeFunction<${typeName}>>().asFunction();');
    emitNewline();
  }

  void emitMethods(List<Method> methods) {
    for (int i = 0; i < methods.length; i++) {
      currentMethod = methods[i];
      currentMethodIndex = i;
      currentMethod.emit();
      currentMethod = null;
      currentMethodIndex = null;
    }
  }

  // Randomly overwrite some methods from the parent classes.
  void emitVirtualMethods() {
    final currentClassTmp = currentClassIndex;
    int parentClass = classParents[currentClassIndex];
    final vcm = <int, List<int>>{};
    // Chase randomly up in class hierarchy.
    while (parentClass >= 0) {
      vcm[parentClass] = <int>[];
      for (int j = 0, n = classMethods[parentClass].length; j < n; j++) {
        // Call methods are presently always already overriden, so we
        // shouldn't override them here.
        if (rollDice(8) && !(classMethods[parentClass][j] is CallMethod)) {
          currentClassIndex = parentClass;
          currentMethod = classMethods[parentClass][j];
          currentMethodIndex = j;
          classMethods[parentClass][j].emit();
          vcm[parentClass].add(currentMethodIndex);
          currentClassIndex = null;
          currentMethod = null;
          currentMethodIndex = null;
        }
      }
      if (coinFlip() || classParents.length > parentClass) {
        break;
      } else {
        parentClass = classParents[parentClass];
      }
    }
    currentClassIndex = currentClassTmp;
    virtualClassMethods.add(vcm);
  }

  void emitClasses() {
    assert(classFields.length == classMethods.length);
    for (int i = 0; i < classFields.length; i++) {
      if (i == 0) {
        classParents.add(-1);
        emit('class X0 ');
      } else {
        final int parentClass = choose(i);
        classParents.add(parentClass);
        if (coinFlip()) {
          // Inheritance
          emit('class X$i extends X${parentClass} ');
        } else {
          // Mixin
          if (classParents[parentClass] >= 0) {
            emit(
                'class X$i extends X${classParents[parentClass]} with X${parentClass} ');
          } else {
            emit('class X$i with X${parentClass} ');
          }
        }
      }
      emitBraceWrapped(() {
        emitVariableDeclarations('$fieldName${i}_', classFields[i]);
        currentClassIndex = i;
        emitVirtualMethods();
        emitMethods(classMethods[currentClassIndex]);
        emitFunctionDefinition('run', () {
          if (i > 0) {
            // FIXME(bkonyi): fix potential issue where we try to apply a class
            // as a mixin when it calls super.
            emitLn('super.run();');
          }
          assert(localVars.isEmpty);
          emitStatements(0);
          assert(localVars.isEmpty);
        }, retType: 'void');
      });
      emitNewline();
      emitNewline();
      emitAndAddExtensionMethods(
          classMethods[currentClassIndex],
          "X${currentClassIndex}",
          "XE${currentClassIndex}",
          "${methodName}${currentClassIndex}_Extension");
      currentClassIndex = null;
    }
  }

  void emitAndAddExtensionMethods(
      List<Method> methodList, className, extensionName, namePrefix,
      {DartType type}) {
    int endIndex = methodList.length;
    methodList.addAll(getMethods(numExtensionMethodsPerClass, numMethodParams,
        MethodType.extensionMethod,
        className: className,
        // Randomly select between named and anonymous extensions.
        extensionName: coinFlip() ? extensionName : "",
        namePrefix: namePrefix,
        type: type));
    emit("extension $extensionName on $className ");
    emitBraceWrapped(() {
      // Emit the newly added methods.
      for (int i = endIndex; i < methodList.length; i++) {
        currentMethod = methodList[i];
        currentMethodIndex = i;
        methodList[i].emit();
        currentMethod = null;
        currentMethodIndex = null;
      }
    });
    emitNewline();
    emitNewline();
  }

  void emitLoadFfiLib() {
    if (ffi) {
      emitLn(
          '// The following throws an uncaught exception if the ffi library ' +
              'is not found.');
      emitLn(
          '// By not catching this exception, we terminate the program with ' +
              'a full stack trace');
      emitLn('// which, in turn, flags the problem prominently');
      emitIfStatement(() => emit('ffiTestFunctions == null'),
          () => emitPrint('Did not load ffi test functions'));
      emitNewline();
    }
  }

  void emitMain() => emitFunctionDefinition('main', () {
        emitLoadFfiLib();

        // Call each global method once.
        for (int i = 0; i < globalMethods.length; i++) {
          String outputName;
          emitTryCatchFinally(
              () => outputName =
                  globalMethods[i].emitCall(1, includeSemicolon: true),
              () => emitPrint('$outputName() throws'));
          emitNewline();
        }

        // Call each class method once.
        for (int i = 0; i < classMethods.length; i++) {
          for (int j = 0; j < classMethods[i].length; j++) {
            String outputName;
            emitNewline();
            emitTryCatchFinally(
                () => outputName =
                    classMethods[i][j].emitCall(1, includeSemicolon: true),
                () => emitPrint('${outputName} throws'));
          }
          // Call each virtual class method once.
          int parentClass = classParents[i];
          while (parentClass >= 0) {
            if (virtualClassMethods[i].containsKey(parentClass)) {
              for (int j = 0;
                  j < virtualClassMethods[i][parentClass].length;
                  j++) {
                String outputName;
                emitNewline();
                emitTryCatchFinally(
                    () => outputName = classMethods[parentClass][j]
                        .emitCall(1, includeSemicolon: true),
                    () => emitPrint('${outputName} throws'));
              }
            }
            parentClass = classParents[parentClass];
          }
        }

        emitNewline();
        emitTryCatchFinally(() {
          emitLn('X${classFields.length - 1}().run();', newline: false);
        }, () {
          emitPrint('X${classFields.length - 1}().run() throws');
        });

        emitNewline();
        emitTryCatchFinally(() {
          String body = '';
          for (int i = 0; i < globalVars.length; i++) {
            body += '\$$varName$i\\n';
          }
          emitPrint('$body');
        }, () => emitPrint('print() throws'));
      });

  //
  // Declarations.
  //

  void emitVariableDeclarations(String name, List<DartType> vars) {
    for (int i = 0; i < vars.length; i++) {
      DartType tp = vars[i];
      final varName = '$name$i';
      emitVariableDeclaration(varName, tp,
          initializerEmitter: () => emitConstructorOrLiteral(0, tp));
    }
    emitNewline();
  }

  void emitVariableDeclaration(String name, DartType tp,
      {Function initializerEmitter,
      bool indent = true,
      bool newline = true,
      bool includeSemicolon = true}) {
    final typeName = tp.name;
    if (indent) {
      emitIndentation();
    }
    emit('$typeName $name', newline: false);
    if (initializerEmitter != null) {
      emit(' = ');
      initializerEmitter();
    }
    if (includeSemicolon) {
      emit(';', newline: newline);
    }
  }

  void emitParDecls(List<DartType> pars) => emitCommaSeparated((int i) {
        DartType tp = pars[i];
        emit('${tp.name} $paramName$i');
      }, pars.length, start: 1);

  //
  // Comments (for FE and analysis tools).
  //

  void emitComment() {
    switch (choose(4)) {
      case 0:
        emitLn('// Single-line comment.');
        break;
      case 1:
        emitLn('/// Single-line documentation comment.');
        break;
      case 2:
        emitLn('/*');
        emitLn(' * Multi-line');
        emitLn(' * comment.');
        emitLn(' */');
        break;
      default:
        emitLn('/**');
        emitLn(' ** Multi-line');
        emitLn(' ** documentation comment.');
        emitLn(' */');
        break;
    }
  }

  //
  // Statements.
  //

  // Emit an assignment statement.
  bool emitAssign() {
    final tp = oneOfSet(dartType.allTypes);
    String assignOp;
    if (DartType.isGrowableType(tp)) {
      // Assignments like *= and += on growable types (String, List, ...)
      // may lead to OOM, especially within loops.
      // TODO: Implement a more specific heuristic that selectively allows
      // modifying assignment operators (like += *=) for growable types.
      assignOp = '=';
    } else {
      // Select one of the assign operations for the given type.
      assignOp = oneOfSet(dartType.assignOps(tp));
      if (assignOp == null) {
        throw 'No assign operation for ${tp.name}';
      }
    }
    emitIndentation();
    // Emit a variable of the lhs type.
    final emittedVar = emitVar(0, tp, isLhs: true);
    RhsFilter rhsFilter = RhsFilter.fromDartType(tp, emittedVar);
    emit(" $assignOp ");
    // Select one of the possible rhs types for the given lhs type and assign
    // operation.
    DartType rhsType = oneOfSet(dartType.assignOpRhs(tp, assignOp));
    if (rhsType == null) {
      throw 'No rhs type for assign ${tp.name} $assignOp';
    }

    emitExpr(0, rhsType, rhsFilter: rhsFilter, includeSemicolon: true);
    return true;
  }

  // Emit a print statement.
  bool emitPrint([String body]) {
    emitLn('print', newline: false);
    emitParenWrapped(() {
      if (body != null) {
        emit("'$body'");
      } else {
        DartType tp = oneOfSet(dartType.allTypes);
        emitExpr(0, tp);
      }
    }, includeSemicolon: true);
    return true;
  }

  // Emit a return statement.
  bool emitReturn() {
    List<DartType> proto = getCurrentProto();
    if (proto == null) {
      emitLn('return;');
    } else {
      emitLn('return ', newline: false);
      emitExpr(0, proto[0], includeSemicolon: true);
    }
    return false;
  }

  // Emit a throw statement.
  bool emitThrow() {
    DartType tp = oneOfSet(dartType.allTypes);
    emitLn('throw ', newline: false);
    emitExpr(0, tp, includeSemicolon: true);
    return false;
  }

  // Emit a one-way if statement.
  bool emitIf1(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1));

  // Emit a two-way if statement.
  bool emitIf2(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1),
      elseBodyEmitter: () => emitStatements(depth + 1));

  // Emit a simple increasing for-loop.
  bool emitFor(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final int i = localVars.length;
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: emitZero, newline: false, indent: false);
      emitBinaryComparison(() => emit(name), '<', emitSmallPositiveInt,
          includeSemicolon: true);
      emit('$name++');
    });
    emitBraceWrapped(() {
      nest++;
      iterVars.add('$localName$i');
      localVars.add(DartType.INT);
      emitStatements(depth + 1);
      localVars.removeLast();
      iterVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership for-in-loop.
  bool emitForIn(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final int i = localVars.length;
    // Select one iterable type to be used in 'for in' statement.
    final iterType = oneOfSet(dartType.iterableTypes1);
    // Get the element type contained within the iterable type.
    final elementType = dartType.elementType(iterType);
    if (elementType == null) {
      throw 'No element type for iteration type ${iterType.name}';
    }
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      emit('${elementType.name} $localName$i in ');
      localVars.add(null); // declared, but don't use
      emitExpr(0, iterType);
      localVars.removeLast(); // will get type
    });
    emitBraceWrapped(() {
      nest++;
      localVars.add(elementType);
      emitStatements(depth + 1);
      localVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership forEach loop.
  bool emitForEach(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    emitIndentation();

    // Select one map type to be used in forEach loop.
    final mapType = oneOfSet(dartType.mapTypes);
    final emittedVar = emitScalarVar(mapType, isLhs: false);
    iterVars.add(emittedVar);
    emit('.forEach');
    final i = localVars.length;
    final j = i + 1;
    emitParenWrapped(() {
      emitParenWrapped(() => emit('$localName$i, $localName$j'));
      emitBraceWrapped(() {
        final int nestTmp = nest;
        // Reset, since forEach cannot break out of own or enclosing context.
        nest = 0;
        // Get the type of the map key and add it to the local variables.
        localVars.add(dartType.indexType(mapType));
        // Get the type of the map values and add it to the local variables.
        localVars.add(dartType.elementType(mapType));
        emitStatements(depth + 1);
        localVars.removeLast();
        localVars.removeLast();
        nest = nestTmp;
      });
    }, includeSemicolon: true);
    return true;
  }

  // Emit a while-loop.
  bool emitWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final int i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: () => emitSmallPositiveInt());
      emitLn('while ', newline: false);
      emitParenWrapped(
          () => emitBinaryComparison(() => emit('--$name'), '>', emitZero));
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
    });
    return true;
  }

  // Emit a do-while-loop.
  bool emitDoWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final int i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT, initializerEmitter: emitZero);
      emitLn('do ', newline: false);
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
      emit(' while ');
      emitParenWrapped(
          () => emitBinaryComparison(
              () => emit('++$name'), '<', emitSmallPositiveInt),
          includeSemicolon: true);
    });
    emitNewline();
    return true;
  }

  // Emit a break/continue when inside iteration.
  bool emitBreakOrContinue(int depth) {
    if (nest > 0) {
      switch (choose(2)) {
        case 0:
          emitLn('continue;');
          return false;
        default:
          emitLn('break;');
          return false;
      }
    }
    return emitAssign(); // resort to assignment
  }

  // Emit a switch statement.
  bool emitSwitch(int depth) {
    emitCase(Function bodyEmitter, {int kase}) {
      if (kase == null) {
        emitLn('default: ', newline: false);
      } else {
        emitLn('case $kase: ', newline: false);
      }
      emitBraceWrapped(() {
        bodyEmitter();
        emitNewline();
        emitLn('break;',
            newline: false); // always generate, avoid FE complaints
      });
    }

    emitLn('switch ', newline: false);
    emitParenWrapped(() => emitExpr(0, DartType.INT));
    emitBraceWrapped(() {
      int start = choose(1 << 32);
      int step = chooseOneUpTo(10);
      final maxCases = 3;
      for (int i = 0; i < maxCases; i++, start += step) {
        emitCase(() => emitStatement(depth + 1),
            kase: (i == 2 && coinFlip()) ? null : start);
        if (i + 1 != maxCases) {
          emitNewline();
        }
      }
    });
    return true;
  }

  // Emit a new program scope that introduces a new local variable.
  bool emitScope(int depth) {
    emitIndentation();
    emitBraceWrapped(() {
      DartType tp = oneOfSet(dartType.allTypes);
      final int i = localVars.length;
      final name = '$localName$i';
      emitVariableDeclaration(name, tp, initializerEmitter: () {
        localVars.add(null); // declared, but don't use
        emitExpr(0, tp);
        localVars.removeLast(); // will get type
      });
      localVars.add(tp);
      emitStatements(depth + 1);
      localVars.removeLast();
    });
    return true;
  }

  // Emit try/catch/finally.
  bool emitTryCatch(int depth) {
    final emitStatementsClosure = () => emitStatements(depth + 1);
    emitLn('try ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn("exit(${oomExitCode});", newline: false));
    emit(' catch (exception, stackTrace) ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    if (coinFlip()) {
      emit(' finally ', newline: false);
      emitBraceWrapped(emitStatementsClosure);
    }
    return true;
  }

  // Emit a single statement.
  bool emitSingleStatement(int depth) {
    // Throw in a comment every once in a while.
    if (rollDice(10)) {
      emitComment();
    }
    // Continuing nested statements becomes less likely as the depth grows.
    if (choose(depth + 1) > stmtDepth) {
      return emitAssign();
    }
    // Possibly nested statement.
    switch (choose(17)) {
      // Favors assignment.
      case 0:
        return emitPrint();
      case 1:
        return emitReturn();
      case 2:
        return emitThrow();
      case 3:
        return emitIf1(depth);
      case 4:
        return emitIf2(depth);
      case 5:
        return emitFor(depth);
      case 6:
        return emitForIn(depth);
      case 7:
        return emitWhile(depth);
      case 8:
        return emitDoWhile(depth);
      case 9:
        return emitBreakOrContinue(depth);
      case 10:
        return emitSwitch(depth);
      case 11:
        return emitScope(depth);
      case 12:
        return emitTryCatch(depth);
      case 13:
        return emitForEach(depth);
      case 14:
        emitLibraryCall(depth, DartType.VOID, includeSemicolon: true);
        return true;
      default:
        return emitAssign();
    }
  }

  // Emit a statement (main entry).
  // Returns true if code *may* fall-through
  // (not made too advanced to avoid FE complaints).
  bool emitStatement(int depth) {
    final resetSkipStmt = processStmtOpen();
    bool ret = emitSingleStatement(depth);
    processStmtClose(resetSkipStmt);
    return ret;
  }

  // Emit statements. Returns true if code may fall-through.
  bool emitStatements(int depth) {
    int s = chooseOneUpTo(numStatements);
    for (int i = 0; i < s; i++) {
      if (!emitStatement(depth)) {
        return false; // rest would be dead code
      }
      if (i + 1 != s) {
        emitNewline();
      }
    }
    return true;
  }

  //
  // Expressions.
  //

  void emitBool() => emit(coinFlip() ? 'true' : 'false');

  void emitNull() => emit("null");

  void emitSmallPositiveInt({int limit = 50, bool includeSemicolon = false}) {
    emit('${choose(limit)}');
    if (includeSemicolon) {
      emit(';');
    }
  }

  void emitSmallNegativeInt() => emit('-${choose(100)}');

  void emitInt() {
    switch (choose(7)) {
      // Favors small ints.
      case 0:
      case 1:
      case 2:
        emitSmallPositiveInt();
        break;
      case 3:
      case 4:
      case 5:
        emitSmallNegativeInt();
        break;
      default:
        emit('${oneOf(interestingIntegers)}');
        break;
    }
  }

  void emitDouble() => emit('${uniform()}');

  void emitNum({bool smallPositiveValue = false}) {
    if (!fp || coinFlip()) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else {
      emitDouble();
    }
  }

  void emitChar() {
    switch (choose(10)) {
      // Favors regular char.
      case 0:
        emit(oneOf(interestingChars));
        break;
      default:
        emit(regularChars[choose(regularChars.length)]);
        break;
    }
  }

  void emitString({int length = 8}) {
    final n = choose(length);
    emit("'");
    for (int i = 0; i < n; i++) {
      emitChar();
    }
    emit("'");
  }

  void emitElementExpr(int depth, DartType tp,
      {RhsFilter rhsFilter, bool isConst = false}) {
    // Inside a constant collection, keep collection elements constants too.
    if (isConst) {
      if (DartType.isCollectionType(tp)) {
        emitConstCollection(depth + 1, tp, rhsFilter: rhsFilter);
        return;
      } else if (tp == DartType.DOUBLE) {
        // Dart does not like floating-point elements. A key would, for
        // example, yield "The key does not have a primitive operator '=='".
        emit('null');
        return;
      }
    }
    // Use literals outside a class or inside a constant collection.
    if (currentMethodIndex == null || isConst) {
      emitLiteral(depth, tp, rhsFilter: rhsFilter);
    } else {
      emitExpr(depth, tp, rhsFilter: rhsFilter);
    }
  }

  void emitElement(int depth, DartType tp,
      {RhsFilter rhsFilter, bool isConst = false}) {
    // Get the element type contained in type tp.
    // E.g. element type of List<String> is String.
    final elementType = dartType.elementType(tp);
    // Decide whether we need to generate Map or List/Set type elements.
    if (DartType.isMapType(tp)) {
      // Emit construct for the map key type.
      final indexType = dartType.indexType(tp);
      emitIndentation();
      emitElementExpr(depth, indexType, rhsFilter: rhsFilter, isConst: isConst);
      emit(' : ');
      // Emit construct for the map value type.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    } else {
      // List and Set types.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    }
  }

  void emitCollectionElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
    int r = (depth <= exprDepth) ? choose(10) : 10;
    // TODO (felih): disable complex collection constructs for new types for
    // now.
    if (!{DartType.MAP_INT_STRING, DartType.LIST_INT, DartType.SET_INT}
        .contains(tp)) {
      emitElement(depth, tp, rhsFilter: rhsFilter);
      return;
    }
    switch (r) {
      // Favors elements over control-flow collections.
      case 0:
        emitLn('...', newline: false); // spread
        emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
        break;
      case 1:
        emitLn('if ', newline: false);
        emitParenWrapped(() =>
            emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter));
        emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        if (coinFlip()) {
          emitNewline();
          emitLn('else ', newline: false);
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        }
        break;
      case 2:
        {
          final int i = localVars.length;
          // TODO (felih): update to use new type system. Add types like
          // LIST_STRING etc.
          emitLn('for ', newline: false);
          emitParenWrapped(() {
            final local = '$localName$i';
            iterVars.add(local);
            // For-loop (induction, list, set).
            localVars.add(null); // declared, but don't use
            switch (choose(3)) {
              case 0:
                emitVariableDeclaration(local, DartType.INT,
                    initializerEmitter: emitZero, indent: false);
                emitBinaryComparison(() => emit(local), '<',
                    () => emitSmallPositiveInt(limit: 16),
                    includeSemicolon: true);
                emit('$local++');
                break;
              case 1:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.LIST_INT,
                    rhsFilter: rhsFilter);
                break;
              default:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.SET_INT,
                    rhsFilter: rhsFilter);
                break;
            }
            localVars.removeLast(); // will get type
          });
          nest++;
          localVars.add(DartType.INT);
          emitNewline();
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
          localVars.removeLast();
          iterVars.removeLast();
          nest--;
          break;
        }
      default:
        emitElement(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  void emitCollection(int depth, DartType tp, {RhsFilter rhsFilter}) =>
      emitWrapped(DartType.isListType(tp) ? const ['[', ']'] : const ['{', '}'],
          () {
        // Collection length decreases as depth increases.
        int collectionLength = max(1, 8 - depth);
        emitCommaSeparated(
            (int _) => emitCollectionElement(depth, tp, rhsFilter: rhsFilter),
            chooseOneUpTo(collectionLength),
            newline: DartType.isMapType(tp));
      }, shouldIndent: DartType.isMapType(tp));

  void emitConstCollection(int depth, DartType tp, {RhsFilter rhsFilter}) =>
      emitWrapped(
          DartType.isListType(tp)
              ? const ['const [', ']']
              : const ['const {', '}'],
          () => emitElement(depth, tp, rhsFilter: rhsFilter, isConst: true),
          shouldIndent: DartType.isMapType(tp));

  void emitLiteral(int depth, DartType tp,
      {bool smallPositiveValue = false, RhsFilter rhsFilter}) {
    // Randomly specialize interface if possible. E.g. num to int.
    tp = maybeSpecializeInterface(tp);
    if (tp == DartType.NULL) {
      emitNull();
    } else if (tp == DartType.BOOL) {
      emitBool();
    } else if (tp == DartType.INT) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else if (tp == DartType.DOUBLE) {
      emitDouble();
    } else if (tp == DartType.NUM) {
      emitNum(smallPositiveValue: smallPositiveValue);
    } else if (tp == DartType.STRING) {
      emitString();
    } else if (tp == DartType.ENDIAN) {
      // The Endian type doesn't have a public constructor, so we emit a
      // library call instead.
      emitLibraryCall(depth, tp);
    } else if (dartType.constructors(tp).isNotEmpty) {
      // Constructors serve as literals for non trivially constructable types.
      // Important note: We have to test for existence of a non trivial
      // constructor before testing for list type assiciation, since some types
      // like ListInt32 are of list type but can not be constructed
      // from a literal.
      emitConstructorOrLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    } else if (DartType.isCollectionType(tp)) {
      final resetExprStmt = processExprOpen(tp);
      emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
      processExprClose(resetExprStmt);
    } else {
      throw 'Can not emit literal for type ${tp.name}';
    }
  }

  // Emit a constructor for a type, this can either be a trivial constructor
  // (i.e. parsed from a literal) or an actual function invocation.
  void emitConstructorOrLiteral(int depth, DartType tp,
      {RhsFilter rhsFilter, bool includeSemicolon = false}) {
    // If there is at least one non trivial constructor for the type tp
    // select one of these constructors.
    if (dartType.hasConstructor(tp)) {
      String constructor = oneOfSet(dartType.constructors(tp));
      // There are two types of constructors, named constructors and 'empty'
      // constructors (e.g. X.fromList(...) and new X(...) respectively).
      // Empty constructors are invoked with new + type name, non-empty
      // constructors are static functions of the type.
      if (constructor.isNotEmpty) {
        emit('${tp.name}.${constructor}');
      } else {
        // New is no longer necessary as of Dart 2, but is still supported.
        // Emit a `new` once in a while to ensure it's covered.
        emit('${rollDice(10) ? "new " : ""}${tp.name}');
      }
      emitParenWrapped(() {
        // Iterate over constructor parameters.
        List<DartType> constructorParameters =
            dartType.constructorParameters(tp, constructor);
        if (constructorParameters == null) {
          throw 'No constructor parameters for ${tp.name}.$constructor';
        }
        emitCommaSeparated((int i) {
          // If we are emitting a constructor parameter, we want to use small
          // values to avoid programs that run out of memory.
          // TODO (felih): maybe allow occasionally?
          emitLiteral(depth + 1, constructorParameters[i],
              smallPositiveValue: true, rhsFilter: rhsFilter);
        }, constructorParameters.length);
      });
    } else {
      // Otherwise type can be constructed from a literal.
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    }
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Pick an existing variable of the given type.
  String pickScalarVar(DartType tp, {bool isLhs = false, RhsFilter rhsFilter}) {
    // Randomly specialize interface type, unless emitting left hand side.
    if (!isLhs) tp = maybeSpecializeInterface(tp);
    // Collect all choices from globals, fields, locals, and parameters.
    Set<String> choices = <String>{};
    for (int i = 0; i < globalVars.length; i++) {
      if (tp == globalVars[i]) choices.add('$varName$i');
    }
    for (int i = 0; i < localVars.length; i++) {
      if (tp == localVars[i]) choices.add('$localName$i');
    }
    List<DartType> fields = getCurrentFields();
    if (fields != null) {
      for (int i = 0; i < fields.length; i++) {
        if (tp == fields[i]) choices.add('$fieldName${currentClassIndex}_$i');
      }
    }
    List<DartType> proto = getCurrentProto();
    if (proto != null) {
      // If recursion is allowed on the current method, the last parameter is
      // the recursion depth parameter. We should avoid reassigning the
      // recursion depth parameter to prevent infinite recursion.
      final int endIndex =
          currentMethod.recursionAllowed ? proto.length - 1 : proto.length;
      for (int i = 1; i < endIndex; i++) {
        if (tp == proto[i]) choices.add('$paramName$i');
      }
    }
    // Make modification of the iteration variable from the loop
    // body less likely.
    if (isLhs) {
      if (!rollDice(100)) {
        Set<String> cleanChoices = choices.difference(Set.from(iterVars));
        if (cleanChoices.isNotEmpty) {
          choices = cleanChoices;
        }
      }
    }
    // Filter out the current lhs of the expression to avoid recursive
    // assignments of the form x = x * x.
    if (rhsFilter != null && rhsFilter.shouldFilter) {
      Set<String> cleanChoices = choices.difference({rhsFilter.lhsVar});
      // If we have other choices of variables, use those.
      if (cleanChoices.isNotEmpty) {
        choices = cleanChoices;
      } else if (!isLhs) {
        // If we are emitting an rhs variable, we can emit a terminal.
        // note that if the variable type is a collection, this might
        // still result in a recursion.
        emitLiteral(0, tp);
        return null;
      }
      // Otherwise we have to risk creating a recursion.
    }
    // Then pick one.
    if (choices.isEmpty) {
      throw 'No variable to emit for type ${tp.name}';
    }

    return '${choices.elementAt(choose(choices.length))}';
  }

  String emitScalarVar(DartType tp, {bool isLhs = false, RhsFilter rhsFilter}) {
    final emittedVar = pickScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
    if (emittedVar != null) {
      if (rhsFilter != null && (emittedVar == rhsFilter.lhsVar)) {
        rhsFilter.consume();
      }
      emit(emittedVar);
    }
    return emittedVar;
  }

  String emitSubscriptedVar(int depth, DartType tp,
      {bool isLhs = false, RhsFilter rhsFilter}) {
    String ret;
    // Check if type tp is an indexable element of some other type.
    if (dartType.isIndexableElementType(tp)) {
      // Select a list or map type that contains elements of type tp.
      final iterType = oneOfSet(dartType.indexableElementTypes(tp));
      // Get the index type for the respective list or map type.
      final indexType = dartType.indexType(iterType);
      // Emit a variable of the selected list or map type.
      ret = emitScalarVar(iterType, isLhs: isLhs, rhsFilter: rhsFilter);
      emitSquareBraceWrapped(() =>
          // Emit an expression resolving into the index type. For
          // collection type, only constant collections are used
          // to avoid rehashing the same value into many entries.
          DartType.isCollectionType(indexType)
              ? emitConstCollection(depth + 1, indexType)
              : emitExpr(depth + 1, indexType));
    } else {
      ret = emitScalarVar(tp,
          isLhs: isLhs, rhsFilter: rhsFilter); // resort to scalar
    }
    return ret;
  }

  String emitVar(int depth, DartType tp,
      {bool isLhs = false, RhsFilter rhsFilter}) {
    switch (choose(2)) {
      case 0:
        return emitScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
        break;
      default:
        return emitSubscriptedVar(depth, tp,
            isLhs: isLhs, rhsFilter: rhsFilter);
        break;
    }
  }

  void emitTerminal(int depth, DartType tp, {RhsFilter rhsFilter}) {
    switch (choose(2)) {
      case 0:
        emitLiteral(depth, tp, rhsFilter: rhsFilter);
        break;
      default:
        emitVar(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  // Emit expression with unary operator: (~(x))
  void emitUnaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
    if (dartType.uniOps(tp).isEmpty) {
      return emitTerminal(depth, tp, rhsFilter: rhsFilter);
    }
    emitParenWrapped(() {
      emit(oneOfSet(dartType.uniOps(tp)));
      emitParenWrapped(() => emitExpr(depth + 1, tp, rhsFilter: rhsFilter));
    });
  }

  // Emit expression with binary operator: (x + y)
  void emitBinaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
    if (dartType.binOps(tp).isEmpty) {
      return emitLiteral(depth, tp);
    }

    String binop = oneOfSet(dartType.binOps(tp));
    List<DartType> binOpParams = oneOfSet(dartType.binOpParameters(tp, binop));

    // Avoid recursive assignments of the form a = a * 100.
    if (binop == "*") {
      rhsFilter?.consume();
    }

    // Reduce the number of operations of type growable * large value
    // as these might lead to timeouts and/or oom errors.
    if (binop == "*" &&
        DartType.isGrowableType(binOpParams[0]) &&
        dartType.isInterfaceOfType(binOpParams[1], DartType.NUM)) {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitLiteral(depth + 1, binOpParams[1], smallPositiveValue: true);
      });
    } else if (binop == "*" &&
        DartType.isGrowableType(binOpParams[1]) &&
        dartType.isInterfaceOfType(binOpParams[0], DartType.NUM)) {
      emitParenWrapped(() {
        emitLiteral(depth + 1, binOpParams[0], smallPositiveValue: true);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    } else {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    }
  }

  // Emit expression with ternary operator: (b ? x : y)
  void emitTernaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) =>
      emitParenWrapped(() {
        emitExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter);
        emit(' ? ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
        emit(' : ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
      });

  // Emit expression with pre/post-increment/decrement operator: (x++)
  void emitPreOrPostExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
    if (tp == DartType.INT) {
      emitParenWrapped(() {
        bool pre = coinFlip();
        if (pre) {
          emitPreOrPostOp(tp);
        }
        emitScalarVar(tp, isLhs: true);
        if (!pre) {
          emitPreOrPostOp(tp);
        }
      });
    } else {
      emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
    }
  }

  bool isTypedDataFloatType(List<DartType> proto) {
    for (int i = 0; i < proto.length; ++i) {
      if (DartLib.typedDataFloatTypes.contains(proto[i])) {
        return true;
      }
    }
    return false;
  }

  // Emit library call.
  void emitLibraryCall(int depth, DartType tp,
      {RhsFilter rhsFilter, bool includeSemicolon = false}) {
    DartLib lib = getLibraryMethod(tp);
    if (lib == null || (!fp && isTypedDataFloatType(lib.proto))) {
      // We cannot find a library method, or we found a library method but its
      // prototype has a floating point type, and fp is disabled. This can only
      // happen for non-void types. In those cases, we resort to a literal.
      assert(tp != DartType.VOID);
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
      return;
    }
    emitParenWrapped(() {
      List<DartType> prototype = lib.proto;
      // Receiver.
      if (prototype[0] != DartType.VOID) {
        emitParenWrapped(() => emitArg(
            depth + 1, prototype[0], lib.getRestriction(0),
            rhsFilter: rhsFilter));
        emit('.');
      }
      // Call.
      emit('${lib.name}');
      // Parameters.
      if (lib.isMethod) {
        emitParenWrapped(() {
          if (prototype[1] != DartType.VOID) {
            emitCommaSeparated(
                (int i) => emitArg(
                    depth + 1, prototype[i], lib.getRestriction(i),
                    rhsFilter: rhsFilter),
                prototype.length,
                start: 1);
          }
        });
      }
      // Add cast to avoid error of double or int being interpreted as num.
      if (dartType.isInterfaceOfType(tp, DartType.NUM)) {
        emit(' as ${tp.name}');
      }
    });
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Helper for a method call.
  bool pickedCall(int depth, DartType tp, List<Method> methods, int m,
      {RhsFilter rhsFilter}) {
    for (int i = m - 1; i >= 0; i--) {
      if (tp == methods[i].returnType) {
        bool isRecursiveCall = (currentMethod == methods[i]);
        if (isRecursiveCall && !methods[i].recursionAllowed) {
          continue;
        }
        methods[i].emitCall(depth + 1,
            rhsFilter: rhsFilter, isRecursiveCall: isRecursiveCall);
        return true;
      }
    }
    return false;
  }

  // Emit method call within the program.
  void emitMethodCall(int depth, DartType tp, {RhsFilter rhsFilter}) {
    // Only call an already emitted method or the current method to avoid mutual recursion.
    if (currentClassIndex == null) {
      // Outside a class but inside a method: call backward in global methods.
      if (currentMethodIndex != null &&
          pickedCall(depth, tp, globalMethods, currentMethodIndex + 1,
              rhsFilter: rhsFilter)) {
        return;
      }
    } else {
      int classIndex = currentClassIndex;
      // Chase randomly up in class hierarchy.
      while (classParents[classIndex] > 0) {
        if (coinFlip()) {
          break;
        }
        classIndex = classParents[classIndex];
      }
      int m1 = 0;
      // Inside a class: try to call backwards into current or parent class
      // methods first.
      if (currentMethodIndex == null || classIndex != currentClassIndex) {
        // If currently emitting the 'run' method or calling into a parent class
        // pick any of the current or parent class methods respectively.
        m1 = classMethods[classIndex].length;
      } else {
        // If calling into the current class from any method other than 'run'
        // pick one of the already emitted methods or the current method.
        // We allow simple recursion but avoid mutual recursion.
        // (to avoid infinite recursions).
        m1 = currentMethodIndex + 1;
      }
      final int m2 = globalMethods.length;
      if (pickedCall(depth, tp, classMethods[classIndex], m1,
              rhsFilter: rhsFilter) ||
          pickedCall(depth, tp, globalMethods, m2, rhsFilter: rhsFilter)) {
        return;
      }
    }
    emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal.
  }

  // Emit expression.
  void emitExpr(int depth, DartType tp,
      {RhsFilter rhsFilter, bool includeSemicolon = false}) {
    final resetExprStmt = processExprOpen(tp);
    // Continuing nested expressions becomes less likely as the depth grows.
    if (choose(depth + 1) > exprDepth) {
      emitTerminal(depth, tp, rhsFilter: rhsFilter);
    } else {
      // Possibly nested expression.
      switch (choose(7)) {
        case 0:
          emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 1:
          emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 2:
          emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 3:
          emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 4:
          emitLibraryCall(depth, tp,
              rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        case 5:
          emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        default:
          emitTerminal(depth, tp, rhsFilter: rhsFilter);
          break;
      }
    }
    processExprClose(resetExprStmt);
    if (includeSemicolon) {
      emit(';');
    }
  }

  //
  // Operators.
  //

  // Emit same type in-out increment operator.
  void emitPreOrPostOp(DartType tp) {
    assert(tp == DartType.INT);
    emit(oneOf(const <String>['++', '--']));
  }

  // Emit one type in, boolean out operator.
  void emitRelOp(DartType tp) {
    if (tp == DartType.INT || tp == DartType.DOUBLE) {
      emit(oneOf(const <String>[' > ', ' >= ', ' < ', ' <= ', ' != ', ' == ']));
    } else {
      emit(oneOf(const <String>[' != ', ' == ']));
    }
  }

  //
  // Library methods.
  //

  // Get a library method that returns given type.
  DartLib getLibraryMethod(DartType tp) =>
      api.typeToLibraryMethods.containsKey(tp)
          ? oneOf(api.typeToLibraryMethods[tp])
          : null;

  // Emit a library argument, possibly subject to restrictions.
  void emitArg(int depth, DartType type, Restriction restriction,
      {RhsFilter rhsFilter}) {
    if ((type == DartType.INT) && (restriction == Restriction.small)) {
      emitSmallPositiveInt();
    } else if ((type == DartType.DOUBLE) && !fp) {
      // resort to INT if floating point is disabled.
      emitExpr(depth, DartType.INT, rhsFilter: rhsFilter);
    } else if ((type == DartType.STRING) &&
        (restriction == Restriction.small)) {
      emitString(length: 2);
    } else {
      emitExpr(depth, type, rhsFilter: rhsFilter);
    }
  }

  //
  // Types.
  //

  List<DartType> fillTypes1({int limit = 4, bool isFfi = false}) {
    final list = <DartType>[];
    for (int i = 0, n = chooseOneUpTo(limit); i < n; i++) {
      if (isFfi) {
        list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
      } else {
        list.add(oneOfSet(dartType.allTypes));
      }
    }
    return list;
  }

  List<List<DartType>> fillTypes2(
      {bool isFfi = false, int limit2 = 4, int limit1 = 4}) {
    final list = <List<DartType>>[];
    for (int i = 0, n = chooseOneUpTo(limit2); i < n; i++) {
      list.add(fillTypes1(limit: limit1, isFfi: isFfi));
    }
    return list;
  }

  List<DartType> getCurrentProto() {
    if (currentClassIndex != null) {
      if (currentMethodIndex != null) {
        return classMethods[currentClassIndex][currentMethodIndex].parameters;
      }
    } else if (currentMethodIndex != null) {
      return globalMethods[currentMethodIndex].parameters;
    }
    return null;
  }

  List<DartType> getCurrentFields() {
    if (currentClassIndex != null) {
      return classFields[currentClassIndex];
    }
    return null;
  }

  void emitFfiType(DartType tp) {
    if (tp == DartType.INT) {
      emit(oneOf(
          const <String>['ffi.Int8', 'ffi.Int16', 'ffi.Int32', 'ffi.Int64']));
    } else if (tp == DartType.DOUBLE) {
      emit(oneOf(const <String>['ffi.Float', 'ffi.Double']));
    } else {
      throw 'Invalid FFI type ${tp.name}';
    }
  }

  void emitFfiTypedef(Method method) {
    List<DartType> pars = method.parameters;
    emit("typedef ${method.name}Type = ");
    emitFfiType(pars[0]);
    emit(' Function');
    emitParenWrapped(
        () => emitCommaSeparated((int i) => emitFfiType(pars[i]), pars.length,
            start: 1),
        includeSemicolon: true);
    emitNewline();
    emitNewline();
  }

  //
  // Output.
  //

  // Emits a newline to the program.
  void emitNewline() => emit('', newline: true);

  // Emits indentation based on the current indentation count.
  void emitIndentation() => file.writeStringSync(' ' * indent);

  // Emits indented line to append to program.
  void emitLn(String line, {bool newline = true}) {
    emitIndentation();
    emit(line, newline: newline);
  }

  // Emits text to append to program.
  void emit(String txt, {bool newline = false}) {
    if (skipStmt || skipExpr) {
      return;
    }
    file.writeStringSync(txt);
    if (newline) {
      file.writeStringSync('\n');
    }
  }

  // Special return code to handle oom errors.
  static const oomExitCode = 254;

  // Random seed used to generate program.
  final int seed;

  // Enables floating-point operations.
  final bool fp;

  // Enables FFI method calls.
  final bool ffi;

  // Disables nested types.
  final bool flatTp;

  // File used for output.
  final RandomAccessFile file;

  // Library and ffi api.
  DartApi api;

  // Program variables.
  Random rand;
  int indent;
  int nest;
  int currentClassIndex;
  Method currentMethod;
  int currentMethodIndex;

  // DartType instance.
  DartType dartType;

  // Types of local variables currently in scope.
  List<DartType> localVars;

  // Types of global variables.
  List<DartType> globalVars;

  // Names of currently active iterator variables.
  // These are tracked to avoid modifications within the loop body,
  // which can lead to infinite loops.
  List<String> iterVars;

  // List of all global methods.
  List<Method> globalMethods;

  // Types of fields over all classes.
  List<List<DartType>> classFields;

  // List of methods over all classes.
  List<List<Method>> classMethods;

  // List of virtual functions per class. Map is from parent class index to List
  // of overloaded functions from that parent.
  List<Map<int, List<int>>> virtualClassMethods;

  // Parent class indices for all classes.
  List<int> classParents;

  // Minimization mode extensions.
  final bool minimize;
  BigInt smask;
  BigInt emask;
  bool skipStmt;
  bool skipExpr;
  bool skipExprCntr;
  int stmtCntr;
  int exprCntr;

  // Interesting characters.
  static const List<String> interestingChars = [
    '\\u2665',
    '\\u{1f600}', // rune
  ];

  // Regular characters.
  static const regularChars =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';

  // Interesting integer values.
  static const List<int> interestingIntegers = [
    0x0000000000000000,
    0x0000000000000001,
    0x000000007fffffff,
    0x0000000080000000,
    0x0000000080000001,
    0x00000000ffffffff,
    0x0000000100000000,
    0x0000000100000001,
    0x000000017fffffff,
    0x0000000180000000,
    0x0000000180000001,
    0x00000001ffffffff,
    0x7fffffff00000000,
    0x7fffffff00000001,
    0x7fffffff7fffffff,
    0x7fffffff80000000,
    0x7fffffff80000001,
    0x7fffffffffffffff,
    0x8000000000000000,
    0x8000000000000001,
    0x800000007fffffff,
    0x8000000080000000,
    0x8000000080000001,
    0x80000000ffffffff,
    0x8000000100000000,
    0x8000000100000001,
    0x800000017fffffff,
    0x8000000180000000,
    0x8000000180000001,
    0x80000001ffffffff,
    0xffffffff00000000,
    0xffffffff00000001,
    0xffffffff7fffffff,
    0xffffffff80000000,
    0xffffffff80000001,
    0xffffffffffffffff
  ];
}

// Generate seed. By default (no user-defined nonzero seed given),
// pick the system's best way of seeding randomness and then pick
// a user-visible nonzero seed.
int getSeed(String userSeed) {
  int seed = int.parse(userSeed);
  if (seed == 0) {
    final rand = Random();
    while (seed == 0) {
      seed = rand.nextInt(1 << 32);
    }
  }
  return seed;
}

/// Main driver when dartfuzz.dart is run stand-alone.
main(List<String> arguments) {
  const kSeed = 'seed';
  const kFp = 'fp';
  const kFfi = 'ffi';
  const kFlat = 'flat';
  const kMini = 'mini';
  const kSMask = 'smask';
  const kEMask = 'emask';
  final parser = ArgParser()
    ..addOption(kSeed,
        help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
    ..addFlag(kFp, help: 'enables floating-point operations', defaultsTo: true)
    ..addFlag(kFfi,
        help: 'enables FFI method calls (default: off)', defaultsTo: false)
    ..addFlag(kFlat,
        help: 'enables flat types (default: off)', defaultsTo: false)
    // Minimization mode extensions.
    ..addFlag(kMini,
        help: 'enables minimization mode (default: off)', defaultsTo: false)
    ..addOption(kSMask,
        help: 'Bitmask indicating which statements to omit'
            '(Bit=1 omits)',
        defaultsTo: '0')
    ..addOption(kEMask,
        help: 'Bitmask indicating which expressions to omit'
            '(Bit=1 omits)',
        defaultsTo: '0');
  try {
    final results = parser.parse(arguments);
    final seed = getSeed(results[kSeed]);
    final fp = results[kFp];
    final ffi = results[kFfi];
    final flatTp = results[kFlat];
    final file = File(results.rest.single).openSync(mode: FileMode.write);
    final minimize = results[kMini];
    final smask = BigInt.parse(results[kSMask]);
    final emask = BigInt.parse(results[kEMask]);
    final dartFuzz = DartFuzz(seed, fp, ffi, flatTp, file,
        minimize: minimize, smask: smask, emask: emask);
    dartFuzz.run();
    file.closeSync();
    // Print information that will be parsed by minimize.py
    if (minimize) {
      // Updated statement mask.
      // This might be different from the input parameter --smask
      // since masking a statement that contains nested statements leads to
      // those being masked as well.
      print(dartFuzz.smask.toRadixString(10));
      // Total number of statements in the generated program.
      print(dartFuzz.stmtCntr);
      // Updated expression mask.
      // This might be different from the input parameter --emask
      // since masking a statement that contains expressions or
      // an expression that contains nested expressions leads to
      // those being masked as well.
      print(dartFuzz.emask.toRadixString(10));
      // Total number of expressions in the generated program.
      print(dartFuzz.exprCntr);
    }
  } catch (e) {
    print('Usage: dart dartfuzz.dart [OPTIONS] FILENAME\n${parser.usage}\n$e');
    exitCode = 255;
  }
}
