// Copyright (c) 2015, 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 test.util.compiler_pool;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:async/async.dart';
import 'package:path/path.dart' as p;
import 'package:pool/pool.dart';

import '../../util/io.dart';
import '../load_exception.dart';

/// A pool of `dart2js` instances.
///
/// This limits the number of compiler instances running concurrently.
class CompilerPool {
  /// The internal pool that controls the number of process running at once.
  final Pool _pool;

  /// Whether to enable colors on dart2js.
  final bool _color;

  /// The currently-active dart2js processes.
  final _processes = new Set<Process>();

  /// Whether [close] has been called.
  bool get _closed => _closeMemo.hasRun;

  /// The memoizer for running [close] exactly once.
  final _closeMemo = new AsyncMemoizer();

  /// Creates a compiler pool that runs up to [concurrency] instances of
  /// `dart2js` at once.
  ///
  /// If [concurrency] isn't provided, it defaults to 4.
  ///
  /// If [color] is true, `dart2js` will be run with colors enabled.
  CompilerPool({int concurrency, bool color: false})
      : _pool = new Pool(concurrency == null ? 4 : concurrency),
        _color = color;

  /// Compile the Dart code at [dartPath] to [jsPath].
  ///
  /// This wraps the Dart code in the standard browser-testing wrapper. If
  /// [packageRoot] is provided, it's used as the package root for the
  /// compilation.
  ///
  /// The returned [Future] will complete once the `dart2js` process completes
  /// *and* all its output has been printed to the command line.
  Future compile(String dartPath, String jsPath, {String packageRoot}) {
    return _pool.withResource(() {
      if (_closed) return null;

      return withTempDir((dir) async {
        var wrapperPath = p.join(dir, "runInBrowser.dart");
        new File(wrapperPath).writeAsStringSync('''
import "package:test/src/runner/browser/iframe_listener.dart";

import "${p.toUri(p.absolute(dartPath))}" as test;

void main(_) {
  IframeListener.start(() => test.main);
}
''');

        var dart2jsPath = p.join(sdkDir, 'bin', 'dart2js');
        if (Platform.isWindows) dart2jsPath += '.bat';

        var args = ["--checked", wrapperPath, "--out=$jsPath"];

        if (packageRoot != null) {
          args.add("--package-root=${p.toUri(p.absolute(packageRoot))}");
        }

        if (_color) args.add("--enable-diagnostic-colors");

        var process = await Process.start(dart2jsPath, args);
        if (_closed) {
          process.kill();
          return;
        }

        _processes.add(process);

        /// Wait until the process is entirely done to print out any output.
        /// This can produce a little extra time for users to wait with no
        /// update, but it also avoids some really nasty-looking interleaved
        /// output. Write both stdout and stderr to the same buffer in case
        /// they're intended to be printed in order.
        var buffer = new StringBuffer();

        await Future.wait([
          _printOutputStream(process.stdout, buffer),
          _printOutputStream(process.stderr, buffer),
        ]);

        var exitCode = await process.exitCode;
        _processes.remove(process);
        if (_closed) return;

        if (buffer.isNotEmpty) print(buffer);

        if (exitCode != 0) throw new LoadException(dartPath, "dart2js failed.");

        _fixSourceMap(jsPath + '.map');
      });
    });
  }

  // TODO(nweiz): Remove this when sdk#17544 is fixed.
  /// Fix up the source map at [mapPath] so that it points to absolute file:
  /// URIs that are resolvable by the browser.
  void _fixSourceMap(String mapPath) {
    var map = JSON.decode(new File(mapPath).readAsStringSync());
    var root = map['sourceRoot'];

    map['sources'] = map['sources'].map((source) {
      var url = Uri.parse(root + source);
      if (url.scheme != '' && url.scheme != 'file') return source;
      if (url.path.endsWith("/runInBrowser.dart")) return "";
      return p.toUri(mapPath).resolveUri(url).toString();
    }).toList();

    new File(mapPath).writeAsStringSync(JSON.encode(map));
  }

  /// Sanitizes the bytes emitted by [stream], converts them to text, and writes
  /// them to [buffer].
  Future _printOutputStream(Stream<List<int>> stream, StringBuffer buffer) {
    return sanitizeForWindows(stream)
        .listen((data) => buffer.write(UTF8.decode(data))).asFuture();
  }

  /// Closes the compiler pool.
  ///
  /// This kills all currently-running compilers and ensures that no more will
  /// be started. It returns a [Future] that completes once all the compilers
  /// have been killed and all resources released.
  Future close() {
    return _closeMemo.runOnce(() async {
      await Future.wait(_processes.map((process) async {
        process.kill();
        await process.exitCode;
      }));
    });
  }
}
