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

// Patch file for the dart:isolate library.

import 'dart:_js_helper' show patch;
import 'dart:_isolate_helper' show CapabilityImpl,
                                   IsolateNatives,
                                   ReceivePortImpl,
                                   RawReceivePortImpl;

@patch
class Isolate {
  static final _currentIsolateCache = IsolateNatives.currentIsolate;

  // `current` must be a getter, not just a final field,
  // to match the external declaration.
  @patch
  static Isolate get current => _currentIsolateCache;

  @patch
  static Future<Uri> get packageRoot {
    throw new UnsupportedError("Isolate.packageRoot");
  }

  @patch
  static Future<Map<String, Uri>> get packageMap {
    throw new UnsupportedError("Isolate.packageMap");
  }

  @patch
  static Future<Isolate> spawn(void entryPoint(message), var message,
                               {bool paused: false, bool errorsAreFatal,
                                SendPort onExit, SendPort onError}) {
    bool forcePause = (errorsAreFatal != null) ||
                      (onExit != null) ||
                      (onError != null);
    try {
      // TODO: Consider passing the errorsAreFatal/onExit/onError values
      //       as arguments to the internal spawnUri instead of setting
      //       them after the isolate has been created.
      return IsolateNatives.spawnFunction(entryPoint, message,
                                          paused || forcePause)
          .then((msg) {
            var isolate = new Isolate(msg[1],
                                      pauseCapability: msg[2],
                                      terminateCapability: msg[3]);
            if (forcePause) {
              if (errorsAreFatal != null) {
                isolate.setErrorsFatal(errorsAreFatal);
              }
              if (onExit != null) {
                isolate.addOnExitListener(onExit);
              }
              if (onError != null) {
                isolate.addErrorListener(onError);
              }
              if (!paused) {
                isolate.resume(isolate.pauseCapability);
              }
            }
            return isolate;
          });
    } catch (e, st) {
      return new Future<Isolate>.error(e, st);
    }
  }

  @patch
  static Future<Isolate> spawnUri(
      Uri uri, List<String> args, var message,
      {bool paused: false,
       SendPort onExit,
       SendPort onError,
       bool errorsAreFatal,
       bool checked,
       Map<String, String> environment,
       Uri packageRoot,
       Map<String, Uri> packageMap}) {
    if (environment != null) throw new UnimplementedError("environment");
    if (packageRoot != null) throw new UnimplementedError("packageRoot");
    if (packageMap != null) throw new UnimplementedError("packageMap");
    bool forcePause = (errorsAreFatal != null) ||
                      (onExit != null) ||
                      (onError != null);
    try {
      if (args is List<String>) {
        for (int i = 0; i < args.length; i++) {
          if (args[i] is! String) {
            throw new ArgumentError("Args must be a list of Strings $args");
          }
        }
      } else if (args != null) {
        throw new ArgumentError("Args must be a list of Strings $args");
      }
      // TODO: Handle [packageRoot]/[packages] somehow, possibly by throwing.
      // TODO: Consider passing the errorsAreFatal/onExit/onError values
      //       as arguments to the internal spawnUri instead of setting
      //       them after the isolate has been created.
      return IsolateNatives.spawnUri(uri, args, message, paused || forcePause)
          .then((msg) {
            var isolate = new Isolate(msg[1],
                                      pauseCapability: msg[2],
                                      terminateCapability: msg[3]);
            if (forcePause) {
              if (errorsAreFatal != null) {
                isolate.setErrorsFatal(errorsAreFatal);
              }
              if (onExit != null) {
                isolate.addOnExitListener(onExit);
              }
              if (onError != null) {
                isolate.addErrorListener(onError);
              }
              if (!paused) {
                isolate.resume(isolate.pauseCapability);
              }
            }
            return isolate;
          });
    } catch (e, st) {
      return new Future<Isolate>.error(e, st);
    }
  }

  @patch
  void _pause(Capability resumeCapability) {
    var message = new List(3)
        ..[0] = "pause"
        ..[1] = pauseCapability
        ..[2] = resumeCapability;
    controlPort.send(message);
  }

  @patch
  void resume(Capability resumeCapability) {
    var message = new List(2)
        ..[0] = "resume"
        ..[1] = resumeCapability;
    controlPort.send(message);
  }

  @patch
  void addOnExitListener(SendPort responsePort, {Object response}) {
    // TODO(lrn): Can we have an internal method that checks if the receiving
    // isolate of a SendPort is still alive?
    var message = new List(3)
        ..[0] = "add-ondone"
        ..[1] = responsePort
        ..[2] = response;
    controlPort.send(message);
  }

  @patch
  void removeOnExitListener(SendPort responsePort) {
    var message = new List(2)
        ..[0] = "remove-ondone"
        ..[1] = responsePort;
    controlPort.send(message);
  }

  @patch
  void setErrorsFatal(bool errorsAreFatal) {
    var message = new List(3)
        ..[0] = "set-errors-fatal"
        ..[1] = terminateCapability
        ..[2] = errorsAreFatal;
    controlPort.send(message);
  }

  @patch
  void kill({int priority: BEFORE_NEXT_EVENT}) {
    controlPort.send(["kill", terminateCapability, priority]);
  }

  @patch
  void ping(SendPort responsePort, {Object response,
                                    int priority: IMMEDIATE}) {
    var message = new List(4)
        ..[0] = "ping"
        ..[1] = responsePort
        ..[2] = priority
        ..[3] = response;
    controlPort.send(message);
  }

  @patch
  void addErrorListener(SendPort port) {
    var message = new List(2)
        ..[0] = "getErrors"
        ..[1] = port;
    controlPort.send(message);
  }

  @patch
  void removeErrorListener(SendPort port) {
    var message = new List(2)
        ..[0] = "stopErrors"
        ..[1] = port;
    controlPort.send(message);
  }
}

/** Default factory for receive ports. */
@patch
class ReceivePort {
  @patch
  factory ReceivePort() = ReceivePortImpl;

  @patch
  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
    return new ReceivePortImpl.fromRawReceivePort(rawPort);
  }
}

@patch
class RawReceivePort {
  @patch
  factory RawReceivePort([void handler(event)]) {
    return new RawReceivePortImpl(handler);
  }
}

@patch
class Capability {
  @patch
  factory Capability() = CapabilityImpl;
}
