// Copyright (c) 2020, 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:async';
import 'dart:io';
import 'dart:isolate';

export '../../../../../benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart'
  show fibonacciRecursive;

final bool isDebugMode = Platform.script.path.contains('Debug');
final bool isSimulator = Platform.script.path.contains('SIM');
final bool isArtificialReloadMode = Platform.executableArguments.any((arg) => [
      '--hot-reload-rollback-test-mode',
      '--hot-reload-test-mode'
    ].contains(arg));

// Implements recursive summation:
//   sum(n) => n == 0 ? 0
//                    : 1 + sum(n-1);
Future sumRecursive(List args) async {
  final SendPort port = args[0];
  final n = args[1];
  if (n == 0) {
    port.send(0);
  } else {
    final rp = ReceivePort();
    await Isolate.spawn(sumRecursive, [rp.sendPort, n - 1]);
    port.send(1 + (await rp.first));
  }
}

// Implements recursive summation via tail calls:
//   sum(n, s) => n == 0 ? s
//                       : sum(n-1, s+1);
Future sumRecursiveTailCall(List args) async {
  final SendPort port = args[0];
  final n = args[1];
  final s = args[2];
  if (n == 0) {
    port.send(s);
  } else {
    await Isolate.spawn(sumRecursiveTailCall, [port, n - 1, s + 1]);
  }
}

enum Command { kRun, kRunAndClose, kClose }

abstract class RingElement {
  Future run(SendPort nextNeighbour, StreamIterator prevNeighbour);
}

class Ring {
  final int size;
  final List<StreamIterator> receivePorts;
  final List<SendPort> controlSendPorts;
  final List<SendPort> dataSendPorts;

  Ring(this.size, this.receivePorts, this.controlSendPorts, this.dataSendPorts);

  static Future<Ring> create(int n) async {
    final ports = <StreamIterator>[];
    final spawnFutures = <Future>[];
    for (int i = 0; i < n; ++i) {
      final port = ReceivePort();
      ports.add(StreamIterator(port));
      spawnFutures
          .add(Isolate.spawn(_ringEntry, port.sendPort, debugName: 'ring-$i'));
    }
    await Future.wait(spawnFutures);
    final controlSendPorts = <SendPort>[];
    final dataSendPorts = <SendPort>[];
    for (int i = 0; i < n; ++i) {
      final si = ports[i];
      await si.moveNext();
      controlSendPorts.add(si.current[0]);
      dataSendPorts.add(si.current[1]);
    }

    return Ring(n, ports, controlSendPorts, dataSendPorts);
  }

  static Future _ringEntry(SendPort port) async {
    final rpControl = ReceivePort();
    final rpData = ReceivePort();
    port.send([rpControl.sendPort, rpData.sendPort]);

    final siControl = StreamIterator(rpControl);
    final siData = StreamIterator(rpData);
    while (await siControl.moveNext()) {
      final List args = siControl.current;
      final command = args[0];
      switch (command) {
        case Command.kRun:
          final RingElement re = args[1];
          final SendPort nextNeighbor = args[2];
          port.send(await re.run(nextNeighbor, siData));
          break;
        case Command.kRunAndClose:
          final RingElement re = args[1];
          final SendPort nextNeighbor = args[2];
          Isolate.exit(port, await re.run(nextNeighbor, siData));
          break;
        case Command.kClose:
          port.send('done');
          rpControl.close();
          rpData.close();
          return;
      }
    }

    throw 'bug';
  }

  Future<List> run(RingElement buildRingElement(int id)) async {
    for (int i = 0; i < size; i++) {
      final nextNeighbor = dataSendPorts[(i + 1) % size];
      controlSendPorts[i]
          .send([Command.kRun, buildRingElement(i), nextNeighbor]);
    }

    final results = await Future.wait(receivePorts.map((si) async {
      await si.moveNext();
      return si.current;
    }).toList());

    return results;
  }

  Future<List> runAndClose(RingElement buildRingElement(int id)) async {
    for (int i = 0; i < size; i++) {
      final nextNeighbor = dataSendPorts[(i + 1) % size];
      controlSendPorts[i]
          .send([Command.kRunAndClose, buildRingElement(i), nextNeighbor]);
    }

    final results = await Future.wait(receivePorts.map((si) async {
      await si.moveNext();
      return si.current;
    }).toList());
    finalize();
    return results;
  }

  Future close() async {
    for (int i = 0; i < size; i++) {
      controlSendPorts[i].send([Command.kClose]);
    }
    final results = await Future.wait(receivePorts.map((si) async {
      await si.moveNext();
      return si.current;
    }).toList());
    finalize();
    return results;
  }

  void finalize() async {
    for (int i = 0; i < size; ++i) {
      await receivePorts[i].cancel();
    }
  }
}

class Tree {
  final int value;
  final Tree? left;
  final Tree? right;

  Tree(this.value, this.left, this.right);

  int get sum => value + (left?.sum ?? 0) + (right?.sum ?? 0);

  Tree get copy => Tree(value, left?.copy, right?.copy);
}

Tree buildTree(int n) {
  if (n == 0) return Tree(0, null, null);
  Tree left = Tree(0, null, null);
  Tree right = Tree(0, null, null);
  for (int i = 1; i < n; ++i) {
    left = Tree(1, left, right);
    right = left.copy;
  }
  return Tree(1, left, right);
}
