// 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
  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'));
