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

library MandelIsolateTest;
import 'dart:async';
import 'dart:isolate';
import 'dart:math';
import '../../pkg/unittest/lib/unittest.dart';

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

main() {
  // Test is really slow in debug builds of the VM.
  SimpleConfiguration configuration = unittestConfiguration;
  configuration.timeout = const Duration(seconds: 480);
  test("Render Mandelbrot in parallel", () {
    final state = new MandelbrotState();
    state._validated.future.then(expectAsync1((result) {
      expect(result, isTrue);
    }));
    for (int i = 0; i < 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);
    int line = _sent++;
    LineProcessorClient.create(this, id).then((final client) {
      client.processLine(line);
    });
  }

  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.write("0");
        output.write(line[j]);
      }
      output.write("\n");
    }
    // print(output);
  }

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


class LineProcessorClient {
  MandelbrotState _state;
  int _id;
  SendPort _port;

  LineProcessorClient(this._state, this._id, this._port);

  static Future<LineProcessorClient> create(MandelbrotState state, int id) {
    ReceivePort reply = new ReceivePort();
    return Isolate.spawn(processLines, reply.sendPort).then((_) {
      return reply.first.then((port) {
        return new LineProcessorClient(state, id, port);
      });
    });
  }

  void processLine(int y) {
    ReceivePort reply = new ReceivePort();
    _port.send([y, reply.sendPort]);
    reply.first.then((List<int> message) {
      _state.notifyProcessedLine(this, y, message);
    });
  }

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

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(SendPort replyPort) {
  ReceivePort port = new ReceivePort();
  port.listen((message) {
    if (message != TERMINATION_MESSAGE) {
      int line = message[0];
      SendPort replyTo = message[1];
      replyTo.send(processLine(line));
    } else {
      port.close();
    }
  });
  replyPort.send(port.sendPort);
}
