// 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: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 '../util/package_config.dart';
import 'configuration.dart';
import 'suite.dart';

/// A regular expression matching the first status line printed by dart2js.
final _dart2jsStatus =
    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 = <Process>{};

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

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

  /// Extra arguments to pass to dart2js.
  final List<String> _extraArgs;

  /// Creates a compiler pool that multiple instances of `dart2js` at once.
  CompilerPool([Iterable<String>? extraArgs])
      : _pool = Pool(Configuration.current.concurrency),
        _extraArgs = extraArgs?.toList() ?? const [];

  /// Compiles [code] 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 code, String jsPath, SuiteConfiguration suiteConfig) {
    return _pool.withResource(() {
      if (_closed) return null;

      return withTempDir((dir) async {
        var wrapperPath = p.join(dir, 'runInBrowser.dart');
        File(wrapperPath).writeAsStringSync(code);

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

        var args = [
          for (var experiment in _enabledExperiments)
            '--enable-experiment=$experiment',
          '--enable-asserts',
          wrapperPath,
          '--out=$jsPath',
          '--packages=${await packageConfigUri}',
          ..._extraArgs,
          ...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 = StringBuffer();

        await Future.wait([
          process.stdout.transform(utf8.decoder).forEach(buffer.write),
          process.stderr.transform(utf8.decoder).forEach(buffer.write),
        ]);

        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 '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 = jsonDecode(File(mapPath).readAsStringSync());
    var root = map['sourceRoot'] as String;

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

    File(mapPath).writeAsStringSync(jsonEncode(map));
  }

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

/// Parses and returns the currently enabled experiments from
/// [Platform.executableArguments].
final List<String> _enabledExperiments = () {
  var experiments = <String>[];
  var itr = Platform.executableArguments.iterator;
  while (itr.moveNext()) {
    var arg = itr.current;
    if (arg == '--enable-experiment') {
      if (!itr.moveNext()) break;
      experiments.add(itr.current);
    } else if (arg.startsWith('--enable-experiment=')) {
      var parts = arg.split('=');
      if (parts.length == 2) {
        experiments.addAll(parts[1].split(','));
      }
    }
  }
  return experiments;
}();
