// 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:async";
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch;

@patch
class Isolate {
  @patch
  static Isolate get current {
    throw new UnsupportedError("Isolate.current");
  }

  @patch
  String get debugName {
    throw new UnsupportedError("Isolate.debugName");
  }

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

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

  @patch
  static Future<Uri> resolvePackageUri(Uri packageUri) {
    if (packageUri.scheme != 'package') {
      return new Future<Uri>.value(packageUri);
    }
    return new Future<Uri>.value(
        _packagesBase.resolveUri(packageUri.replace(scheme: '')));
  }

  @patch
  static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
      {bool paused: false,
      bool errorsAreFatal,
      SendPort onExit,
      SendPort onError}) {
    throw new UnsupportedError("Isolate.spawn");
  }

  @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,
      Uri packageConfig,
      bool automaticPackageResolution: false}) {
    throw new UnsupportedError("Isolate.spawnUri");
  }

  @patch
  void _pause(Capability resumeCapability) {
    throw new UnsupportedError("Isolate._pause");
  }

  @patch
  void resume(Capability resumeCapability) {
    throw new UnsupportedError("Isolate.resume");
  }

  @patch
  void addOnExitListener(SendPort responsePort, {Object response}) {
    throw new UnsupportedError("Isolate.addOnExitListener");
  }

  @patch
  void removeOnExitListener(SendPort responsePort) {
    throw new UnsupportedError("Isolate.removeOnExitListener");
  }

  @patch
  void setErrorsFatal(bool errorsAreFatal) {
    throw new UnsupportedError("Isolate.setErrorsFatal");
  }

  @patch
  void kill({int priority: beforeNextEvent}) {
    throw new UnsupportedError("Isolate.kill");
  }

  @patch
  void ping(SendPort responsePort, {Object response, int priority: immediate}) {
    throw new UnsupportedError("Isolate.ping");
  }

  @patch
  void addErrorListener(SendPort port) {
    throw new UnsupportedError("Isolate.addErrorListener");
  }

  @patch
  void removeErrorListener(SendPort port) {
    throw new UnsupportedError("Isolate.removeErrorListener");
  }
}

@patch
class ReceivePort {
  @patch
  factory ReceivePort() = _ReceivePortImpl;

  @patch
  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
    throw new UnsupportedError('new ReceivePort.fromRawReceivePort');
  }
}

class _ReceivePortImpl extends Stream implements ReceivePort {
  StreamSubscription listen(void onData(var event),
      {Function onError, void onDone(), bool cancelOnError}) {
    throw new UnsupportedError("ReceivePort.listen");
  }

  void close() {}

  SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
}

@patch
class RawReceivePort {
  @patch
  factory RawReceivePort([Function handler]) {
    throw new UnsupportedError('new RawReceivePort');
  }
}

@patch
class Capability {
  @patch
  factory Capability() {
    throw new UnsupportedError('new Capability');
  }
}

/// Returns the base path added to Uri.base to resolve `package:` Uris.
///
/// This is used by `Isolate.resolvePackageUri` to load resources. The default
/// value is `packages/` but users can override this by using the
/// `defaultPackagesBase` hook.
Uri _packagesBase = Uri.base.resolve(JS('String', r'self.defaultPackagesBase'));
