// Copyright (c) 2013, 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 pub.load_transformers;

import 'dart:async';
import 'dart:convert';
import 'dart:isolate';

import 'package:barback/barback.dart';
// TODO(nweiz): don't import from "src" once issue 14966 is fixed.
import 'package:barback/src/internal_asset.dart';
import 'package:source_maps/source_maps.dart';
import 'package:stack_trace/stack_trace.dart';

import '../barback.dart';
import '../dart.dart' as dart;
import '../log.dart' as log;
import '../utils.dart';
import 'build_environment.dart';

/// A Dart script to run in an isolate.
///
/// This script serializes one or more transformers defined in a Dart library
/// and marshals calls to and from them with the host isolate.
const _TRANSFORMER_ISOLATE = """
import 'dart:async';
import 'dart:isolate';
import 'dart:convert';
import 'dart:mirrors';

import '<<URL_BASE>>/packages/source_maps/span.dart';
import '<<URL_BASE>>/packages/stack_trace/stack_trace.dart';
import '<<URL_BASE>>/packages/barback/barback.dart';
// TODO(nweiz): don't import from "src" once issue 14966 is fixed.
import '<<URL_BASE>>/packages/barback/src/internal_asset.dart';

/// Sets up the initial communication with the host isolate.
void main(_, SendPort replyTo) {
  var port = new ReceivePort();
  replyTo.send(port.sendPort);
  port.first.then((wrappedMessage) {
    _respond(wrappedMessage, (message) {
      var library = Uri.parse(message['library']);
      var configuration = JSON.decode(message['configuration']);
      var mode = new BarbackMode(message['mode']);
      return initialize(library, configuration, mode).
          map(_serializeTransformerOrGroup).toList();
    });
  });
}

/// Loads all the transformers and groups defined in [uri].
///
/// Loads the library, finds any Transformer or TransformerGroup subclasses in
/// it, instantiates them with [configuration] and [mode], and returns them.
Iterable initialize(Uri uri, Map configuration, BarbackMode mode) {
  var mirrors = currentMirrorSystem();
  var transformerClass = reflectClass(Transformer);
  var groupClass = reflectClass(TransformerGroup);

  // TODO(nweiz): if no valid transformers are found, throw an error message
  // describing candidates and why they were rejected.
  return mirrors.libraries[uri].declarations.values.map((declaration) {
    if (declaration is! ClassMirror) return null;
    var classMirror = declaration;
    if (classMirror.isPrivate) return null;
    if (classMirror.isAbstract) return null;
    if (!classIsA(classMirror, transformerClass) &&
        !classIsA(classMirror, groupClass)) {
      return null;
    }

    var constructor = getConstructor(classMirror, 'asPlugin');
    if (constructor == null) return null;
    if (constructor.parameters.isEmpty) {
      if (configuration.isNotEmpty) return null;
      return classMirror.newInstance(const Symbol('asPlugin'), []).reflectee;
    }
    if (constructor.parameters.length != 1) return null;

    return classMirror.newInstance(const Symbol('asPlugin'),
        [new BarbackSettings(configuration, mode)]).reflectee;
  }).where((classMirror) => classMirror != null);
}

/// A wrapper for a [Transform] that's in the host isolate.
///
/// This retrieves inputs from and sends outputs and logs to the host isolate.
class ForeignTransform implements Transform {
  /// The port with which we communicate with the host isolate.
  ///
  /// This port and all messages sent across it are specific to this transform.
  final SendPort _port;

  final Asset primaryInput;

  TransformLogger get logger => _logger;
  TransformLogger _logger;

  /// Creates a transform from a serializable map sent from the host isolate.
  ForeignTransform(Map transform)
      : _port = transform['port'],
        primaryInput = deserializeAsset(transform['primaryInput']) {
    _logger = new TransformLogger((assetId, level, message, span) {
      _call(_port, {
        'type': 'log',
        'level': level.name,
        'message': message,
        'assetId': assetId == null ? null : _serializeId(assetId),
        'span': span == null ? null : _serializeSpan(span)
      });
    });
  }

  Future<Asset> getInput(AssetId id) {
    return _call(_port, {
      'type': 'getInput',
      'id': _serializeId(id)
    }).then(deserializeAsset);
  }

  Future<String> readInputAsString(AssetId id, {Encoding encoding}) {
    if (encoding == null) encoding = UTF8;
    return getInput(id).then((input) => input.readAsString(encoding: encoding));
  }

  Stream<List<int>> readInput(AssetId id) =>
      _futureStream(getInput(id).then((input) => input.read()));

  void addOutput(Asset output) {
    _call(_port, {
      'type': 'addOutput',
      'output': serializeAsset(output)
    });
  }
}

/// Returns the mirror for the root Object type.
ClassMirror get objectMirror => reflectClass(Object);

// TODO(nweiz): clean this up when issue 13248 is fixed.
MethodMirror getConstructor(ClassMirror classMirror, String constructor) {
  var name = new Symbol("\${MirrorSystem.getName(classMirror.simpleName)}"
      ".\$constructor");
  var candidate = classMirror.declarations[name];
  if (candidate is MethodMirror && candidate.isConstructor) return candidate;
  return null;
}

// TODO(nweiz): get rid of this when issue 12439 is fixed.
/// Returns whether or not [mirror] is a subtype of [superclass].
///
/// This includes [superclass] being mixed in to or implemented by [mirror].
bool classIsA(ClassMirror mirror, ClassMirror superclass) {
  if (mirror == superclass) return true;
  if (mirror == objectMirror) return false;
  return classIsA(mirror.superclass, superclass) ||
      mirror.superinterfaces.any((int) => classIsA(int, superclass));
}

/// Converts [transformerOrGroup] into a serializable map.
Map _serializeTransformerOrGroup(transformerOrGroup) {
  if (transformerOrGroup is Transformer) {
    return _serializeTransformer(transformerOrGroup);
  } else {
    assert(transformerOrGroup is TransformerGroup);
    return _serializeTransformerGroup(transformerOrGroup);
  }
}

/// Converts [transformer] into a serializable map.
Map _serializeTransformer(Transformer transformer) {
  var port = new ReceivePort();
  port.listen((wrappedMessage) {
    _respond(wrappedMessage, (message) {
      if (message['type'] == 'isPrimary') {
        return transformer.isPrimary(deserializeAsset(message['asset']));
      } else {
        assert(message['type'] == 'apply');

        // Make sure we return null so that if the transformer's [apply] returns
        // a non-serializable value it doesn't cause problems.
        return transformer.apply(
            new ForeignTransform(message['transform'])).then((_) => null);
      }
    });
  });

  return {
    'type': 'Transformer',
    'toString': transformer.toString(),
    'port': port.sendPort
  };
}

// Converts [group] into a serializable map.
Map _serializeTransformerGroup(TransformerGroup group) {
  return {
    'type': 'TransformerGroup',
    'toString': group.toString(),
    'phases': group.phases.map((phase) {
      return phase.map(_serializeTransformerOrGroup).toList();
    }).toList()
  };
}

/// Converts a serializable map into an [AssetId].
AssetId _deserializeId(Map id) => new AssetId(id['package'], id['path']);

/// Converts [id] into a serializable map.
Map _serializeId(AssetId id) => {'package': id.package, 'path': id.path};

/// Converts [span] into a serializable map.
Map _serializeSpan(Span span) {
  // TODO(nweiz): convert FileSpans to FileSpans.
  return {
    'type': 'fixed',
    'sourceUrl': span.sourceUrl,
    'start': _serializeLocation(span.start),
    'text': span.text,
    'isIdentifier': span.isIdentifier
  };
}

/// Converts [location] into a serializable map.
Map _serializeLocation(Location location) {
  // TODO(nweiz): convert FileLocations to FileLocations.
  return {
    'type': 'fixed',
    'sourceUrl': location.sourceUrl,
    'offset': location.offset,
    'line': location.line,
    'column': location.column
  };
}

/// Responds to a message sent by [_call].
///
/// [wrappedMessage] is the raw message sent by [_call]. This unwraps it and
/// passes the contents of the message to [callback], then sends the return
/// value of [callback] back to [_call]. If [callback] returns a Future or
/// throws an error, that will also be sent.
void _respond(wrappedMessage, callback(message)) {
  var replyTo = wrappedMessage['replyTo'];
  new Future.sync(() => callback(wrappedMessage['message']))
      .then((result) => replyTo.send({'type': 'success', 'value': result}))
      .catchError((error, stackTrace) {
    // TODO(nweiz): at least MissingInputException should be preserved here.
    replyTo.send({
      'type': 'error',
      'error': CrossIsolateException.serialize(error, stackTrace)
    });
  });
}

/// Wraps [message] and sends it across [port], then waits for a response which
/// should be sent using [_respond].
///
/// The returned Future will complete to the value or error returned by
/// [_respond].
Future _call(SendPort port, message) {
  var receivePort = new ReceivePort();
  port.send({
    'message': message,
    'replyTo': receivePort.sendPort
  });

  return receivePort.first.then((response) {
    if (response['type'] == 'success') return response['value'];
    assert(response['type'] == 'error');
    return new Future.error(
        new CrossIsolateException.deserialize(response['error']));
  });
}

/// An exception that was originally raised in another isolate.
///
/// Exception objects can't cross isolate boundaries in general, so this class
/// wraps as much information as can be consistently serialized.
class CrossIsolateException implements Exception {
  /// The name of the type of exception thrown.
  ///
  /// This is the return value of [error.runtimeType.toString()]. Keep in mind
  /// that objects in different libraries may have the same type name.
  final String type;

  /// The exception's message, or its [toString] if it didn't expose a `message`
  /// property.
  final String message;

  /// The exception's stack chain, or `null` if no stack chain was available.
  final Chain stackTrace;

  /// Loads a [CrossIsolateException] from a serialized representation.
  ///
  /// [error] should be the result of [CrossIsolateException.serialize].
  CrossIsolateException.deserialize(Map error)
      : type = error['type'],
        message = error['message'],
        stackTrace = error['stack'] == null ? null :
            new Chain.parse(error['stack']);

  /// Serializes [error] to an object that can safely be passed across isolate
  /// boundaries.
  static Map serialize(error, [StackTrace stack]) {
    if (stack == null && error is Error) stack = error.stackTrace;
    return {
      'type': error.runtimeType.toString(),
      'message': getErrorMessage(error),
      'stack': stack == null ? null : new Chain.forTrace(stack).toString()
    };
  }

  String toString() => "\$message\\n\$stackTrace";
}

/// A regular expression to match the exception prefix that some exceptions'
/// [Object.toString] values contain.
final _exceptionPrefix = new RegExp(r'^([A-Z][a-zA-Z]*)?(Exception|Error): ');

/// Get a string description of an exception.
///
/// Many exceptions include the exception class name at the beginning of their
/// [toString], so we remove that if it exists.
String getErrorMessage(error) =>
  error.toString().replaceFirst(_exceptionPrefix, '');

/// Returns a buffered stream that will emit the same values as the stream
/// returned by [future] once [future] completes. If [future] completes to an
/// error, the return value will emit that error and then close.
Stream _futureStream(Future<Stream> future) {
  var controller = new StreamController(sync: true);
  future.then((stream) {
    stream.listen(
        controller.add,
        onError: controller.addError,
        onDone: controller.close);
  }).catchError((e, stackTrace) {
    controller.addError(e, stackTrace);
    controller.close();
  });
  return controller.stream;
}

Stream callbackStream(Stream callback()) {
  var subscription;
  var controller;
  controller = new StreamController(onListen: () {
    subscription = callback().listen(controller.add,
        onError: controller.addError,
        onDone: controller.close);
  },
      onCancel: () => subscription.cancel(),
      onPause: () => subscription.pause(),
      onResume: () => subscription.resume(),
      sync: true);
  return controller.stream;
}
""";

/// Load and return all transformers and groups from the library identified by
/// [id].
Future<Set> loadTransformers(BuildEnvironment environment, TransformerId id) {
  return id.getAssetId(environment.barback).then((assetId) {
    var path = assetId.path.replaceFirst('lib/', '');
    // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
    var baseUrl = baseUrlForAddress(environment.server.address,
                                    environment.server.port);
    var uri = '$baseUrl/packages/${id.package}/$path';
    var code = 'import "$uri";\n' +
        _TRANSFORMER_ISOLATE.replaceAll('<<URL_BASE>>', baseUrl);
    log.fine("Loading transformers from $assetId");

    var port = new ReceivePort();
    return dart.runInIsolate(code, port.sendPort)
        .then((_) => port.first)
        .then((sendPort) {
      return _call(sendPort, {
        'library': uri,
        'mode': environment.mode.name,
        // TODO(nweiz): support non-JSON-encodable configuration maps.
        'configuration': JSON.encode(id.configuration)
      }).then((transformers) {
        transformers = transformers.map(_deserializeTransformerOrGroup).toSet();
        log.fine("Transformers from $assetId: $transformers");
        return transformers;
      });
    }).catchError((error, stackTrace) {
      if (error is! dart.CrossIsolateException) throw error;
      if (error.type != 'IsolateSpawnException') throw error;
      // TODO(nweiz): don't parse this as a string once issues 12617 and 12689
      // are fixed.
      if (!error.message.split('\n')[1].startsWith('import "$uri";')) {
        throw error;
      }

      // If there was an IsolateSpawnException and the import that actually
      // failed was the one we were loading transformers from, throw an
      // application exception with a more user-friendly message.
      fail('Transformer library "package:${id.package}/$path" not found.',
          error, stackTrace);
    });
  });
}

/// A wrapper for a transformer that's in a different isolate.
class _ForeignTransformer extends Transformer {
  /// The port with which we communicate with the child isolate.
  ///
  /// This port and all messages sent across it are specific to this
  /// transformer.
  final SendPort _port;

  /// The result of calling [toString] on the transformer in the isolate.
  final String _toString;

  _ForeignTransformer(Map map)
      : _port = map['port'],
        _toString = map['toString'];

  Future<bool> isPrimary(Asset asset) {
    return _call(_port, {
      'type': 'isPrimary',
      'asset': serializeAsset(asset)
    });
  }

  Future apply(Transform transform) {
    return _call(_port, {
      'type': 'apply',
      'transform': _serializeTransform(transform)
    });
  }

  String toString() => _toString;
}

/// A wrapper for a transformer group that's in a different isolate.
class _ForeignGroup implements TransformerGroup {
  final Iterable<Iterable> phases;

  /// The result of calling [toString] on the transformer group in the isolate.
  final String _toString;

  _ForeignGroup(Map map)
      : phases = map['phases'].map((phase) {
          return phase.map(_deserializeTransformerOrGroup).toList();
        }).toList(),
        _toString = map['toString'];

  String toString() => _toString;
}

/// Converts a serializable map into a [Transformer] or a [TransformerGroup].
_deserializeTransformerOrGroup(Map map) {
  if (map['type'] == 'Transformer') return new _ForeignTransformer(map);
  assert(map['type'] == 'TransformerGroup');
  return new _ForeignGroup(map);
}

/// Converts [transform] into a serializable map.
Map _serializeTransform(Transform transform) {
  var receivePort = new ReceivePort();
  receivePort.listen((wrappedMessage) {
    _respond(wrappedMessage, (message) {
      if (message['type'] == 'getInput') {
        return transform.getInput(_deserializeId(message['id']))
            .then((asset) => serializeAsset(asset));
      }

      if (message['type'] == 'addOutput') {
        transform.addOutput(deserializeAsset(message['output']));
        return null;
      }

      assert(message['type'] == 'log');
      var method;
      if (message['level'] == 'Info') {
        method = transform.logger.info;
      } else if (message['level'] == 'Warning') {
        method = transform.logger.warning;
      } else {
        assert(message['level'] == 'Error');
        method = transform.logger.error;
      }

      var assetId = message['assetId'] == null ? null :
        _deserializeId(message['assetId']);
      var span = message['span'] == null ? null :
        _deserializeSpan(message['span']);
      method(message['message'], asset: assetId, span: span);
    });
  });

  return {
    'port': receivePort.sendPort,
    'primaryInput': serializeAsset(transform.primaryInput)
  };
}

/// Converts a serializable map into an [AssetId].
AssetId _deserializeId(Map id) => new AssetId(id['package'], id['path']);

/// Converts a serializable map into a [Span].
Span _deserializeSpan(Map span) {
  assert(span['type'] == 'fixed');
  var location = _deserializeLocation(span['start']);
  return new FixedSpan(span['sourceUrl'], location.offset, location.line,
      location.column, text: span['text'], isIdentifier: span['isIdentifier']);
}

/// Converts a serializable map into a [Location].
Location _deserializeLocation(Map location) {
  assert(location['type'] == 'fixed');
  return new FixedLocation(location['offset'], location['sourceUrl'],
      location['line'], location['column']);
}

/// Converts [id] into a serializable map.
Map _serializeId(AssetId id) => {'package': id.package, 'path': id.path};

/// Responds to a message sent by [_call].
///
/// [wrappedMessage] is the raw message sent by [_call]. This unwraps it and
/// passes the contents of the message to [callback], then sends the return
/// value of [callback] back to [_call]. If [callback] returns a Future or
/// throws an error, that will also be sent.
void _respond(wrappedMessage, callback(message)) {
  var replyTo = wrappedMessage['replyTo'];
  syncFuture(() => callback(wrappedMessage['message']))
      .then((result) => replyTo.send({'type': 'success', 'value': result}))
      .catchError((error, stackTrace) {
    // TODO(nweiz): at least MissingInputException should be preserved here.
    replyTo.send({
      'type': 'error',
      'error': dart.CrossIsolateException.serialize(error, stackTrace)
    });
  });
}

/// Wraps [message] and sends it across [port], then waits for a response which
/// should be sent using [_respond].
///
/// The returned Future will complete to the value or error returned by
/// [_respond].
Future _call(SendPort port, message) {
  var receivePort = new ReceivePort();
  port.send({
    'message': message,
    'replyTo': receivePort.sendPort
  });

  return Chain.track(receivePort.first).then((response) {
    if (response['type'] == 'success') return response['value'];
    assert(response['type'] == 'error');
    return new Future.error(
        new dart.CrossIsolateException.deserialize(response['error']),
        new Chain.current());
  });
}
