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

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

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

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

/// A regular expression matching the first status line printed by dart2js.
final _dart2jsStatus =
    new RegExp(r"^Dart file \(.*\) compiled to JavaScript: .*\n?");

/// A pool of `dart2js` instances.
///
/// This limits the number of compiler instances running concurrently.
class CompilerPool {
  /// The test runner configuration.
  final _config = Configuration.current;

  /// The internal pool that controls the number of process running at once.
  final Pool _pool;

  /// 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 multiple instances of `dart2js` at once.
  CompilerPool() : _pool = new Pool(Configuration.current.concurrency);

  /// Compile the Dart code at [dartPath] to [jsPath].
  ///
  /// This wraps the Dart code in the standard browser-testing wrapper.
  ///
  /// 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, SuiteConfiguration suiteConfig) {
    return _pool.withResource(() {
      if (_closed) return null;

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

          import "package:test/src/runner/plugin/remote_platform_helpers.dart";
          import "package:test/src/runner/browser/post_message_channel.dart";

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

          main(_) async {
            var channel = serializeSuite(() => test.main, hidePrints: false);
            postMessageChannel().pipe(channel);
          }
        ''');

        var dart2jsPath = _config.dart2jsPath;
        if (Platform.isWindows) dart2jsPath += '.bat';

        var args = [
          "--checked",
          wrapperPath,
          "--out=$jsPath",
          await PackageResolver.current.processArgument
        ]..addAll(suiteConfig.dart2jsArgs);

        if (_config.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;

        var output = buffer.toString().replaceFirst(_dart2jsStatus, '');
        if (output.isNotEmpty) print(output);

        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;
      }));
    });
  }
}
