// Copyright (c) 2012, 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:isolate");

class Fields {
  Fields(int i, int j) : fld1 = i, fld2 = j, fld5 = true {}
  int fld1;
  final int fld2;
  static int fld3;
  static const int fld4 = 10;
  bool fld5;
}
class FieldsTest {
  static Fields testMain() {
    Fields obj = new Fields(10, 20);
    Expect.equals(10, obj.fld1);
    Expect.equals(20, obj.fld2);
    Expect.equals(10, Fields.fld4);
    Expect.equals(true, obj.fld5);
    return obj;
  }
}
// Benchpress: A collection of micro-benchmarks.
// Ported from internal v8 benchmark suite.

class Error {
  static void error(String msg) {
    throw msg;
  }
}

// F i b o n a c c i
class Fibonacci {
  static int fib(int n) {
    if (n <= 1) return 1;
    return fib(n - 1) + fib(n - 2);
  }
}

class FibBenchmark extends BenchmarkBase {
  const FibBenchmark() : super("Fibonacci");

  void warmup() {
    Fibonacci.fib(10);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var result = Fibonacci.fib(20);
    if (result != 10946)
      Error.error("Wrong result: $result. Should be: 10946.");
  }

  static void main() {
    new FibBenchmark().report();
  }
}

// L o o p
class Loop {
  static int loop(int outerIterations) {
    int sum = 0;
    for (int i = 0; i < outerIterations; i++) {
      for (int j = 0; j < 100; j++) {
        sum++;
      }
    }
    return sum;
  }
}

class LoopBenchmark extends BenchmarkBase {
  const LoopBenchmark() : super("Loop");

  void warmup() {
    Loop.loop(10);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var result = Loop.loop(200);
    if (result != 20000)
      Error.error("Wrong result: $result. Should be: 20000");
  }

  static void main() {
    new LoopBenchmark().report();
  }
}

// T o w e r s
class TowersDisk {
  final int size;
  TowersDisk next;

  TowersDisk(size) : this.size = size, next = null {}
}

class Towers {
  List<TowersDisk> piles;
  int movesDone;
  Towers(int disks) : piles = new List<TowersDisk>(3), movesDone = 0 {
    build(0, disks);
  }

  void build(int pile, int disks) {
    for (var i = disks - 1; i >= 0; i--) {
      push(pile, new TowersDisk(i));
    }
  }

  void push(int pile, TowersDisk disk) {
    TowersDisk top = piles[pile];
    if ((top !== null) && (disk.size >= top.size))
      Error.error("Cannot put a big disk on a smaller disk.");
    disk.next = top;
    piles[pile] = disk;
  }

  TowersDisk pop(int pile) {
    var top = piles[pile];
    if (top === null)
      Error.error("Attempting to remove a disk from an empty pile.");
    piles[pile] = top.next;
    top.next = null;
    return top;
  }

  void moveTop(int from, int to) {
    push(to, pop(from));
    movesDone++;
  }

  void move(int from, int to, int disks) {
    if (disks == 1) {
      moveTop(from, to);
    } else {
      int other = 3 - from - to;
      move(from, other, disks - 1);
      moveTop(from, to);
      move(other, to, disks - 1);
    }
  }
}

class TowersBenchmark extends BenchmarkBase {
  const TowersBenchmark() : super("Towers");

  void warmup() {
    new Towers(6).move(0, 1, 6);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var towers = new Towers(13);
    towers.move(0, 1, 13);
    if (towers.movesDone != 8191) {
      var moves = towers.movesDone;
      Error.error("Error in result: $moves should be: 8191");
    }
  }

  static void main() {
    new TowersBenchmark().report();
  }
}

// S i e v e
class SieveBenchmark extends BenchmarkBase {
  const SieveBenchmark() : super("Sieve");

  static int sieve(int size) {
    int primeCount = 0;
    List<bool> flags = new List<bool>(size + 1);
    for (int i = 1; i < size; i++) flags[i] = true;
    for (int i = 2; i < size; i++) {
      if (flags[i]) {
        primeCount++;
        for (int k = i + 1; k <= size; k += i)
          flags[k - 1] = false;
      }
    }
    return primeCount;
  }


  void warmup() {
    sieve(100);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = sieve(1000);
    if (result != 168)
      Error.error("Wrong result: $result should be: 168");
  }

  static void main() {
    new SieveBenchmark().report();
  }
}

// P e r m u t e
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Permute {
  int permuteCount;
  Permute() {}

  void swap(int n, int k, List<int> list) {
    int tmp = list[n];
    list[n] = list[k];
    list[k] = tmp;
  }

  void doPermute(int n, List<int> list) {
    permuteCount++;
    if (n != 1) {
      doPermute(n - 1, list);
      for (int k = n - 1; k >= 1; k--) {
        swap(n, k, list);
        doPermute(n - 1, list);
        swap(n, k, list);
      }
    }
  }

  int permute(int size) {
    permuteCount = 0;
    List<int> list = new List<int>(size);
    for (int i = 1; i < size; i++) list[i] = i - 1;
    doPermute(size - 1, list);
    return permuteCount;
  }
}

class PermuteBenchmark extends BenchmarkBase {
  const PermuteBenchmark() : super("Permute");

  void warmup() {
    new Permute().permute(4);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = new Permute().permute(8);
    if (result != 8660)
      Error.error("Wrong result: $result should be: 8660");
  }

  static void main() {
    new PermuteBenchmark().report();
  }
}

// Q u e e n s
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Queens {
  static bool tryQueens(int i,
                        List<bool> a,
                        List<bool> b,
                        List<bool> c,
                        List<int> x) {
    int j = 0;
    bool q = false;
    while ((!q) && (j != 8)) {
      j++;
      q = false;
      if (b[j] && a[i + j] && c[i - j + 7]) {
        x[i] = j;
        b[j] = false;
        a[i + j] = false;
        c[i - j + 7] = false;
        if (i < 8) {
          q = tryQueens(i + 1, a, b, c, x);
          if (!q) {
            b[j] = true;
            a[i + j] = true;
            c[i - j + 7] = true;
          }
        } else {
          q = true;
        }
      }
    }
    return q;
  }

  static void queens() {
    List<bool> a = new List<bool>(9);
    List<bool> b = new List<bool>(17);
    List<bool> c = new List<bool>(15);
    List<int> x = new List<int>(9);
    b[1] = false;
    for (int i = -7; i <= 16; i++) {
      if ((i >= 1) && (i <= 8)) a[i] = true;
      if (i >= 2) b[i] = true;
      if (i <= 7) c[i + 7] = true;
    }

    if (!tryQueens(1, b, a, c, x))
      Error.error("Error in queens");
  }
}

class QueensBenchmark extends BenchmarkBase {
  const QueensBenchmark() : super("Queens");

  void warmup() {
    Queens.queens();
  }

  void exercise() {
    Queens.queens();
  }

  static void main() {
    new QueensBenchmark().report();
  }
}


// R e c u r s e
class Recurse {
  static int recurse(int n) {
    if (n <= 0) return 1;
    recurse(n - 1);
    return recurse(n - 1);
  }
}

class RecurseBenchmark extends BenchmarkBase {
  const RecurseBenchmark() : super("Recurse");

  void warmup() {
    Recurse.recurse(7);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    Recurse.recurse(13);
  }

  static void main() {
    new RecurseBenchmark().report();
  }
}


// S u m
class SumBenchmark extends BenchmarkBase {
  const SumBenchmark() : super("Sum");

  static int sum(int start, int end) {
    var sum = 0;
    for (var i = start; i <= end; i++) sum += i;
    return sum;
  }

  void warmup() {
    sum(1, 1000);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = sum(1, 10000);
    if (result != 50005000)
      Error.error("Wrong result: $result should be 50005000");
  }

  static void main() {
    new SumBenchmark().report();
  }
}


// H e l p e r   f u n c t i o n s   f o r   s o r t s
class Random {
  static const int INITIAL_SEED = 74755;
  int seed;
  Random() : seed = INITIAL_SEED {}

  int random() {
    seed = ((seed * 1309) + 13849) % 65536;
    return seed;
  }
}

//
class SortData {
  List<int> list;
  int min;
  int max;

  SortData(int length) {
    Random r = new Random();
    list = new List<int>(length);
    for (int i = 0; i < length; i++) list[i] = r.random();

    int min, max;
    min = max = list[0];
    for (int i = 0; i < length; i++) {
      int e = list[i];
      if (e > max) max = e;
      if (e < min) min = e;
    }

    this.min = min;
    this.max = max;
  }

  void check() {
    List<int> a = list;
    int len = a.length;
    if ((a[0] != min) || a[len - 1] != max)
      Error.error("List is not sorted");
    for (var i = 1; i < len; i++) {
      if (a[i - 1] > a[i]) Error.error("List is not sorted");
    }
  }
}


// B u b b l e S o r t
class BubbleSort {
  static void sort(List<int> a) {
    int len = a.length;
    for (int i = len - 2; i >= 0; i--) {
      for (int j = 0; j <= i; j++) {
        int c = a[j];
        int n = a[j + 1];
        if (c > n) {
          a[j] = n;
          a[j + 1] = c;
        }
      }
    }
  }
}

class BubbleSortBenchmark extends BenchmarkBase {
  const BubbleSortBenchmark() : super("BubbleSort");

  void warmup() {
    SortData data = new SortData(30);
    BubbleSort.sort(data.list);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    SortData data = new SortData(130);
    BubbleSort.sort(data.list);
    data.check();
  }

  static void main() {
    new BubbleSortBenchmark().report();
  }
}

// Q u i c k S o r t
class QuickSort {
  static void sort(List<int> a, int low, int high) {
    int pivot = a[(low + high) >> 1];
    int i = low;
    int j = high;
    while (i <= j) {
      while (a[i] < pivot) i++;
      while (pivot < a[j]) j--;
      if (i <= j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
        i++;
        j--;
      }
    }

    if (low < j) sort(a, low, j);
    if (i < high) sort(a, i, high);
  }
}

class QuickSortBenchmark extends BenchmarkBase {
  const QuickSortBenchmark() : super("QuickSort");

  void warmup() {
    SortData data = new SortData(100);
    QuickSort.sort(data.list, 0, data.list.length - 1);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    SortData data = new SortData(800);
    QuickSort.sort(data.list, 0, data.list.length - 1);
    data.check();
  }

  static void main() {
    new QuickSortBenchmark().report();
  }
}


// T r e e S o r t
class TreeNodePress {
  int value;
  TreeNodePress left;
  TreeNodePress right;

  TreeNodePress(int n) : value = n {}

  void insert(int n) {
    if (n < value) {
      if (left === null) left = new TreeNodePress(n);
      else left.insert(n);
    } else {
      if (right === null) right = new TreeNodePress(n);
      else right.insert(n);
    }
  }

  void check() {
    TreeNodePress left = this.left;
    TreeNodePress right = this.right;
    int value = this.value;

    return ((left === null) || ((left.value < value) && left.check())) &&
           ((right === null) || ((right.value >= value) && right.check()));
  }
}

class TreeSort {
  static void sort(List<int> a) {
    int len = a.length;
    TreeNodePress tree = new TreeNodePress(a[0]);
    for (var i = 1; i < len; i++) tree.insert(a[i]);
    if (!tree.check()) Error.error("Invalid result, tree not sorted");
  }
}

class TreeSortBenchmark extends BenchmarkBase {
  const TreeSortBenchmark() : super("TreeSort");

  void warmup() {
    TreeSort.sort(new SortData(100).list);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    TreeSort.sort(new SortData(1000).list);
  }
}


// T a k
class TakBenchmark extends BenchmarkBase {
  const TakBenchmark() : super("Tak");

  static void tak(int x, int y, int z) {
    if (y >= x) return z;
    return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
  }

  void warmup() {
    tak(9, 6, 3);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    tak(18, 12, 6);
  }

  static void main() {
    new TakBenchmark().report();
  }
}


// T a k l
class ListElement {
  final int length;
  final ListElement next;

  const ListElement(int length, ListElement next)
  : this.length = length,
    this.next = next;

  static ListElement makeList(int length) {
    if (length == 0) return null;
    return new ListElement(length, makeList(length - 1));
  }

  static bool isShorter(ListElement x, ListElement y) {
    ListElement xTail = x;
    ListElement yTail = y;
    while (yTail !== null) {
      if (xTail === null) return true;
      xTail = xTail.next;
      yTail = yTail.next;
    }
    return false;
  }
}

class Takl {
  static ListElement takl(ListElement x, ListElement y, ListElement z) {
    if (ListElement.isShorter(y, x)) {
      return takl(takl(x.next, y, z),
                  takl(y.next, z, x),
                  takl(z.next, x, y));
    } else {
      return z;
    }
  }
}

class TaklBenchmark extends BenchmarkBase {
  const TaklBenchmark() : super("Takl");

  void warmup() {
    Takl.takl(ListElement.makeList(8),
              ListElement.makeList(4),
              ListElement.makeList(3));
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    ListElement result = Takl.takl(ListElement.makeList(15),
                                   ListElement.makeList(10),
                                   ListElement.makeList(6));
    if (result.length != 10) {
      int len = result.length;
      Error.error("Wrong result: $len should be: 10");
    }
  }

  static void main() {
    new TaklBenchmark().report();
  }
}

// M a i n

class BenchPress {
  static void mainWithArgs(List<String> args) {
    List<BenchmarkBase> benchmarks = [
        new BubbleSortBenchmark(),
        new FibBenchmark(),
        new LoopBenchmark(),
        new PermuteBenchmark(),
        new QueensBenchmark(),
        new QuickSortBenchmark(),
        new RecurseBenchmark(),
        new SieveBenchmark(),
        new SumBenchmark(),
        new TakBenchmark(),
        new TaklBenchmark(),
        new TowersBenchmark(),
        new TreeSortBenchmark(),
    ];
    if (args.length > 0) {
      String benchName = args[0];
      bool foundBenchmark = false;
      benchmarks.forEach((bench) {
        if (bench.name == benchName) {
          foundBenchmark = true;
          bench.report();
        }
      });
      if (!foundBenchmark) {
        Error.error("Benchmark not found: $benchName");
      }
      return;
    }
    double logMean = 0.0;
    benchmarks.forEach((bench) {
      double benchScore = bench.measure();
      String name = bench.name;
      print("$name: $benchScore");
      logMean += Math.log(benchScore);
    });
    logMean = logMean / benchmarks.length;
    double score = Math.pow(Math.E, logMean);
    print("BenchPress (average): $score");
  }

  // TODO(floitsch): let main accept arguments from the command line.
  static void main() {
    mainWithArgs([]);
  }
}

class BenchmarkBase {
  final String name;

  // Empty constructor.
  const BenchmarkBase(String name) : this.name = name;

  // The benchmark code.
  // This function is not used, if both [warmup] and [exercise] are overwritten.
  void run() { }

  // Runs a short version of the benchmark. By default invokes [run] once.
  void warmup() {
    run();
  }

  // Exercices the benchmark. By default invokes [run] 10 times.
  void exercise() {
    for (int i = 0; i < 10; i++) {
      run();
    }
  }

  // Not measured setup code executed prior to the benchmark runs.
  void setup() { }

  // Not measures teardown code executed after the benchark runs.
  void teardown() { }

  // Measures the score for this benchmark by executing it repeately until
  // time minimum has been reached.
  static double measureFor(Function f, int timeMinimum) {
    int time = 0;
    int iter = 0;
    Date start = new Date.now();
    while (time < timeMinimum) {
      f();
      time = (new Date.now().difference(start)).inMilliseconds;
      iter++;
    }
    // Force double result by using a double constant.
    return (1000.0 * iter) / time;
  }

  // Measures the score for the benchmark and returns it.
  double measure() {
    setup();
    // Warmup for at least 100ms. Discard result.
    measureFor(() { this.warmup(); }, -100);
    // Run the benchmark for at least 2000ms.
    double result = measureFor(() { this.exercise(); }, -2000);
    teardown();
    return result;
  }

  void report() {
    double score = measure();
    print("name: $score");
  }

}
class Logger {
  static print(object) {
    printobject(object);
  }
  static printobject(obj) { }
}


//
// Dromaeo ObjectString
// Adapted from Mozilla JavaScript performance test suite.
// Microtests of strings (concatenation, methods).


class ObjectString extends BenchmarkBase {

  const ObjectString() : super("Dromaeo.ObjectString");

  static void main() {
    new ObjectString().report();
  }

  static void print(String str) {
    print(str);
  }

  String getRandomString(int characters) {
    var result = "";
    for (var i = 0; i < characters; i++) {
      result += Strings.
          createFromCodePoints([(25 * Math.random()).toInt() + 97]);
    }
    result += result;
    result += result;
    return result;
  }

  void run() {
    //JS Dromeaeo uses 16384
    final ITERATE1 = 384;
    //JS Dromeaeo uses 80000
    final ITERATE2 = 80;
    //JS Dromeaeo uses 5000
    final ITERATE3 = 50;
    //JS Dromeaeo uses 5000
    final ITERATE4 = 1;
    //JS Dromaeo uses 5000
    final ITERATE5 = 1000;

    var result;
    var text = getRandomString(ITERATE1);

    ConcatStringBenchmark.test(ITERATE2);
    ConcatStringFromCharCodeBenchmark.test(ITERATE2);
    StringSplitBenchmark.test(text);
    StringSplitOnCharBenchmark.test(text);
    text += text;
    CharAtBenchmark.test(text, ITERATE3);
    NumberBenchmark.test(text, ITERATE3);
    CharCodeAtBenchmark.test(text, ITERATE3);
    IndexOfBenchmark.test(text, ITERATE3);
    LastIndexOfBenchmark.test(text, ITERATE3);
    SliceBenchmark.test(text, ITERATE4);
    SubstrBenchmark.test(text, ITERATE4);
    SubstringBenchmark.test(text, ITERATE4);
    ToLowerCaseBenchmark.test(text, ITERATE5);
    ToUpperCaseBenchmark.test(text, ITERATE5);
    ComparingBenchmark.test(text, ITERATE5);
  }
}

class ConcatStringBenchmark {
  ConcatStringBenchmark() {}

  static String test(var iterations) {
    var str = "";
    for (var i = 0; i < iterations; i++) {
      str += "a";
    }
    return str;
  }
}

class ConcatStringFromCharCodeBenchmark {
  ConcatStringFromCharCodeBenchmark() {}

  static String test(var iterations) {
    var str = "";
    for (var i = 0; i < (iterations / 2); i++) {
      str += Strings.createFromCodePoints([97]);
    }
    return str;
  }
}

class StringSplitBenchmark {
  StringSplitBenchmark() {}

  static List<String> test(String input) {
    return input.split("");
  }
}

class StringSplitOnCharBenchmark {
  StringSplitOnCharBenchmark() {}

  static List<String> test(String input) {
    String multiple = input;
    multiple += multiple;
    multiple += multiple;
    multiple += multiple;
    multiple += multiple;
    return multiple.split("a");
  }
}

class CharAtBenchmark {
  CharAtBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input[0];
      str = input[input.length - 1];
      str = input[150]; //set it to 15000
      str = input[120]; //set it to 12000
    }
    return str;
  }
}

class NumberBenchmark {
  NumberBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input[0];
      str = input[input.length - 1];
      str = input[150]; //set it to 15000
      str = input[100]; //set it to 10000
      str = input[50]; //set it to 5000
    }
    return str;
  }
}


class CharCodeAtBenchmark {
  CharCodeAtBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.charCodeAt(0);
      str = input.charCodeAt(input.length - 1);
      str = input.charCodeAt(150); //set it to 15000
      str = input.charCodeAt(100); //set it to 10000
      str = input.charCodeAt(50); //set it to 5000
    }
    return str;
  }
}

class IndexOfBenchmark {
  IndexOfBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.indexOf("a", 0);
      str = input.indexOf("b", 0);
      str = input.indexOf("c", 0);
      str = input.indexOf("d", 0);
    }
    return str;
  }
}

class LastIndexOfBenchmark {
  LastIndexOfBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.lastIndexOf("a", input.length - 1);
      str = input.lastIndexOf("b", input.length - 1);
      str = input.lastIndexOf("c", input.length - 1);
      str = input.lastIndexOf("d", input.length - 1);
    }
    return str;
  }
}

class SliceBenchmark {
  SliceBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length - 1);
      str = input.substring(0, 5);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 1);
      str = input.substring(150, 155); //set to 15000 and 15005
      str = input.substring(120, input.length-1); //set to 12000
    }
    return str;
  }
}

class SubstrBenchmark {
  SubstrBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length-1);
      str = input.substring(0, 4);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 6);
      str = input.substring(150, 154); //set to 15000 and 15005
      str = input.substring(120, 124); //set to 12000
    }
    return str;
  }
}

class SubstringBenchmark {
  SubstringBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length - 1);
      str = input.substring(0, 4);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 2);
      str = input.substring(150, 154); //set to 15000 and 15005
      str = input.substring(120, input.length - 2); //set to 12000
    }
    return str;

  }
}

class ToLowerCaseBenchmark {
  ToLowerCaseBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < (iterations / 1000); j++) {
      str = Ascii.toLowerCase(input);
    }
    return str;
  }
}

class ToUpperCaseBenchmark {
  ToUpperCaseBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < (iterations / 1000); j++) {
      str = Ascii.toUpperCase(input);
    }
    return str;
  }
}

class ComparingBenchmark {
  ComparingBenchmark() {}

  static bool test(String input, var iterations) {
    var tmp = "a${input}a";
    var tmp2 = "a${input}a";
    var res;
    for (var j = 0; j < (iterations / 1000); j++) {
      res = (tmp.compareTo(tmp2) == 0);
      res = (tmp.compareTo(tmp2) < 0);
      res = (tmp.compareTo(tmp2) > 0);
    }
    return res;
  }
}

// Benchmarks basic message communication between two isolates.

class Benchmark1 {

  static const MESSAGES = 10000;
  static const INIT_MESSAGE = 0;
  static const TERMINATION_MESSAGE = -1;
  static const WARMUP_TIME = 1000;
  static const RUN_TIME = 1000;
  static const RUNS = 5;


  static int run() {
    return _run;
  }

  static void add_result(var opsms) {
    _run++;
    _opsms += opsms;
  }

  static void get_result() {
    return _opsms / _run;
  }

  static void init() {
    _run = 0;
    _opsms = 0.0;
  }

  static void main() {
    init();
    PingPongGame pingPongGame = new PingPongGame.play();
  }

  static var _run;
  static var _opsms;
}

class PingPongGame {

  PingPongGame.play()
      : _ping = new ReceivePort(),
        _pingPort = _ping.toSendPort(),
        _pong = null,
        _warmedup = false,
        _iterations = 0 {
    SendPort _pong = spawnFunction(pong);
    play();
  }

  void startRound() {
    _iterations++;
    _pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
  }

  void evaluateRound() {
    int time = (new Date.now().difference(_start)).inMilliseconds;
    if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
      startRound();
    } else if (!_warmedup) {
      _warmedup = true;
      _start = new Date.now();
      _iterations = 0;
      startRound();
    } else if (_warmedup && time < Benchmark1.RUN_TIME) {
      startRound();
    } else {
      shutdown();
      Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
      if (Benchmark1.run() < Benchmark1.RUNS) {
        new PingPongGame.play();
      } else {
        print("PingPong: ", Benchmark1.get_result());
      }
    }
  }

  void play() {
    _ping.receive((int message, SendPort replyTo) {
      if (message < Benchmark1.MESSAGES) {
        _pong.send(++message, null);
      } else {
        evaluateRound();
      }
    });
    _start = new Date.now();
    startRound();
  }

  void shutdown() {
    _pong.send(Benchmark1.TERMINATION_MESSAGE, null);
    _ping.close();
  }

  Date _start;
  SendPort _pong;
  SendPort _pingPort;
  ReceivePort _ping;
  bool _warmedup;
  int _iterations;
}

void pong() {
  port.receive((message, SendPort replyTo) {
    if (message == Benchmark1.INIT_MESSAGE) {
      replyTo.send(message, null);
    } else if (message == Benchmark1.TERMINATION_MESSAGE) {
      port.close();
    } else {
      replyTo.send(message, null);
    }
  });
}


class ManyGenericInstanceofTest {
  static testMain() {
    for (int i = 0; i < 5000; i++) {
      GenericInstanceof.testMain();
    }
  }
}

// ---------------------------------------------------------------------------
// THE REST OF THIS FILE COULD BE AUTOGENERATED
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// tests/isolate/spawn_test.dart
// ---------------------------------------------------------------------------

spawn_test_main() {
  test("spawn a new isolate", () {
    SendPort port = spawnFunction(entry);
    port.call(42).then(expectAsync1((message) {
      Expect.equals(42, message);
    }));
  });
}

void entry() {
  port.receive((message, SendPort replyTo) {
    Expect.equals(42, message);
    replyTo.send(42, null);
    port.close();
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/isolate_negative_test.dart
// ---------------------------------------------------------------------------

void isolate_negative_entry() {
  port.receive((ignored, replyTo) {
    replyTo.send("foo", null);
  });
}

isolate_negative_test_main() {
  test("ensure isolate code is executed", () {
    SendPort port = spawnFunction(isolate_negative_entry);
    port.call("foo").then(expectAsync1((message) {
      Expect.equals(true, "Expected fail");   // <=-------- Should fail here.
    }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/message_test.dart
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// Message passing test.
// ---------------------------------------------------------------------------

class MessageTest {
  static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
  static const List list2 = const [null, list1, list1, list1, list1];
  static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
  static const Map map1 = const {
    "a=1" : 1, "b=2" : 2, "c=3" : 3,
  };
  static const Map map2 = const {
    "list1" : list1, "list2" : list2, "list3" : list3,
  };
  static const List list4 = const [map1, map2];
  static const List elms = const [
      list1, list2, list3, list4,
  ];

  static void VerifyMap(Map expected, Map actual) {
    Expect.equals(true, expected is Map);
    Expect.equals(true, actual is Map);
    Expect.equals(expected.length, actual.length);
    testForEachMap(key, value) {
      if (value is List) {
        VerifyList(value, actual[key]);
      } else {
        Expect.equals(value, actual[key]);
      }
    }
    expected.forEach(testForEachMap);
  }

  static void VerifyList(List expected, List actual) {
    for (int i = 0; i < expected.length; i++) {
      if (expected[i] is List) {
        VerifyList(expected[i], actual[i]);
      } else if (expected[i] is Map) {
        VerifyMap(expected[i], actual[i]);
      } else {
        Expect.equals(expected[i], actual[i]);
      }
    }
  }

  static void VerifyObject(int index, var actual) {
    var expected = elms[index];
    Expect.equals(true, expected is List);
    Expect.equals(true, actual is List);
    Expect.equals(expected.length, actual.length);
    VerifyList(expected, actual);
  }
}

pingPong() {
  int count = 0;
  port.receive((var message, SendPort replyTo) {
    if (message == -1) {
      port.close();
      replyTo.send(count, null);
    } else {
      // Check if the received object is correct.
      if (count < MessageTest.elms.length) {
        MessageTest.VerifyObject(count, message);
      }
      // Bounce the received object back so that the sender
      // can make sure that the object matches.
      replyTo.send(message, null);
      count++;
    }
  });
}

message_test_main() {
  test("send objects and receive them back", () {
    SendPort remote = spawnFunction(pingPong);
    // Send objects and receive them back.
    for (int i = 0; i < MessageTest.elms.length; i++) {
      var sentObject = MessageTest.elms[i];
      // TODO(asiva): remove this local var idx once thew new for-loop
      // semantics for closures is implemented.
      var idx = i;
      remote.call(sentObject).then(expectAsync1((var receivedObject) {
        MessageTest.VerifyObject(idx, receivedObject);
      }));
    }

    // Send recursive objects and receive them back.
    List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
    List local_list2 = [null, local_list1, local_list1 ];
    List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
    List sendObject = new List(5);
    sendObject[0] = local_list1;
    sendObject[1] = sendObject;
    sendObject[2] = local_list2;
    sendObject[3] = sendObject;
    sendObject[4] = local_list3;
    remote.call(sendObject).then((var replyObject) {
      Expect.equals(true, sendObject is List);
      Expect.equals(true, replyObject is List);
      Expect.equals(sendObject.length, replyObject.length);
      Expect.equals(true, replyObject[1] === replyObject);
      Expect.equals(true, replyObject[3] === replyObject);
      Expect.equals(true, replyObject[0] === replyObject[2][1]);
      Expect.equals(true, replyObject[0] === replyObject[2][2]);
      Expect.equals(true, replyObject[2] === replyObject[4][0]);
      Expect.equals(true, replyObject[0][0] === replyObject[0][2]);
      // Bigint literals are not canonicalized so do a == check.
      Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
    });

    // Shutdown the MessageServer.
    remote.call(-1).then(expectAsync1((int message) {
        Expect.equals(MessageTest.elms.length + 1, message);
      }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/request_reply_test.dart
// ---------------------------------------------------------------------------

void request_reply_entry() {
  port.receive((message, SendPort replyTo) {
    replyTo.send(message + 87);
    port.close();
  });
}

void request_reply_main() {
  test("call", () {
    SendPort port = spawnFunction(request_reply_entry);
    port.call(42).then(expectAsync1((message) {
      Expect.equals(42 + 87, message);
    }));
  });

  test("send", () {
    SendPort port = spawnFunction(request_reply_entry);
    ReceivePort reply = new ReceivePort();
    port.send(99, reply.toSendPort());
    reply.receive(expectAsync2((message, replyTo) {
      Expect.equals(99 + 87, message);
      reply.close();
    }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/count_test.dart
// ---------------------------------------------------------------------------

void countMessages() {
  int count = 0;
  port.receive((int message, SendPort replyTo) {
    if (message == -1) {
      Expect.equals(10, count);
      replyTo.send(-1, null);
      port.close();
      return;
    }
    Expect.equals(count, message);
    count++;
    replyTo.send(message * 2, null);
  });
}

void count_main() {
  test("count 10 consecutive messages", () {
    int count = 0;
    SendPort remote = spawnFunction(countMessages);
    ReceivePort local = new ReceivePort();
    SendPort reply = local.toSendPort();

    local.receive(expectAsync2((int message, SendPort replyTo) {
      if (message == -1) {
        Expect.equals(11, count);
        local.close();
        return;
      }

      Expect.equals((count - 1) * 2, message);
      remote.send(count++, reply);
      if (count == 10) {
        remote.send(-1, reply);
      }
    }, count: 11));
    remote.send(count++, reply);
  });
}


// ---------------------------------------------------------------------------
// tests/isolate/mandel_isolate_test.dart
// ---------------------------------------------------------------------------

const TERMINATION_MESSAGE = -1;
const N = 100;
const ISOLATES = 20;

mandel_main() {
  test("Render Mandelbrot in parallel", () {
    final state = new MandelbrotState();
    state._validated.future.then(expectAsync1((result) {
      expect(result, isTrue);
    }));
    for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
  });
}


class MandelbrotState {

  MandelbrotState() {
    _result = new List<List<int>>(N);
    _lineProcessedBy = new List<LineProcessorClient>(N);
    _sent = 0;
    _missing = N;
    _validated = new Completer<bool>();
  }

  void startClient(int id) {
    assert(_sent < N);
    final client = new LineProcessorClient(this, id);
    client.processLine(_sent++);
  }

  void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
    assert(_result[y] === null);
    _result[y] = line;
    _lineProcessedBy[y] = client;

    if (_sent != N) {
      client.processLine(_sent++);
    } else {
      client.shutdown();
    }

    // If all lines have been computed, validate the result.
    if (--_missing == 0) {
      _printResult();
      _validateResult();
    }
  }

  void _validateResult() {
    // TODO(ngeoffray): Implement this.
    _validated.complete(true);
  }

  void _printResult() {
    var output = new StringBuffer();
    for (int i = 0; i < _result.length; i++) {
      List<int> line = _result[i];
      for (int j = 0; j < line.length; j++) {
        if (line[j] < 10) output.add("0");
        output.add(line[j]);
      }
      output.add("\n");
    }
    // print(output);
  }

  List<List<int>> _result;
  List<LineProcessorClient> _lineProcessedBy;
  int _sent;
  int _missing;
  Completer<bool> _validated;
}


class LineProcessorClient {

  LineProcessorClient(MandelbrotState this._state, int this._id) {
    _port = spawnFunction(processLines);
  }

  void processLine(int y) {
    _port.call(y).then((List<int> message) {
      _state.notifyProcessedLine(this, y, message);
    });
  }

  void shutdown() {
    _port.send(TERMINATION_MESSAGE, null);
  }

  MandelbrotState _state;
  int _id;
  SendPort _port;
}

List<int> processLine(int y) {
  double inverseN = 2.0 / N;
  double Civ = y * inverseN - 1.0;
  List<int> result = new List<int>(N);
  for (int x = 0; x < N; x++) {
    double Crv = x * inverseN - 1.5;

    double Zrv = Crv;
    double Ziv = Civ;

    double Trv = Crv * Crv;
    double Tiv = Civ * Civ;

    int i = 49;
    do {
      Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
      Zrv = Trv - Tiv + Crv;

      Trv = Zrv * Zrv;
      Tiv = Ziv * Ziv;
    } while (((Trv + Tiv) <= 4.0) && (--i > 0));

    result[x] = i;
  }
  return result;
}

void processLines() {
  port.receive((message, SendPort replyTo) {
    if (message == TERMINATION_MESSAGE) {
      assert(replyTo == null);
      port.close();
    } else {
      replyTo.send(processLine(message), null);
    }
  });
}
