// 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.

// @dart = 2.9

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.89';

// 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');
    emitLn('// @dart=2.7');
    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;
  }
}
