content: // Copyright 2023 Google Inc. Use of this source code is governed by an
  // MIT-style license that can be found in the LICENSE file or at
  // https://opensource.org/licenses/MIT.
  
  import 'dart:math' as math;
  
  import '../io.dart';
  import '../stylesheet_graph.dart';
  import '../util/map.dart';
  import 'compile_stylesheet.dart';
  import 'concurrent/vm.dart'
      // Never load the isolate library when compiling to JS.
      if (dart.library.js) 'concurrent/js.dart';
  import 'options.dart';
  
  /// Compiles the stylesheets concurrently and returns whether all stylesheets are compiled
  /// successfully.
  Future<bool> compileStylesheets(
    ExecutableOptions options,
    StylesheetGraph graph,
    Map<String?, String?> sourcesToDestinations, {
    bool ifModified = false,
  }) async {
    var errorsWithStackTraces = switch ([...sourcesToDestinations.pairs]) {
      // Concurrency does add some overhead, so avoid it in the common case of
      // compiling a single stylesheet.
      [(var source, var destination)] => [
          await compileStylesheet(
            options,
            graph,
            source,
            destination,
            ifModified: ifModified,
          ),
        ],
      var pairs => await Future.wait([
          for (var (source, destination) in pairs)
            compileStylesheetConcurrently(
              options,
              graph,
              source,
              destination,
              ifModified: ifModified,
            ),
        ], eagerError: options.stopOnError),
    };
  
    var printedError = false;
  
    // Print all errors in deterministic order.
    for (var errorWithStackTrace in errorsWithStackTraces) {
      if (errorWithStackTrace == null) continue;
      var (code, error, stackTrace) = errorWithStackTrace;
  
      // We let the highest exitCode take precedence for deterministic behavior.
      exitCode = math.max(exitCode, code);
  
      _printError(error, stackTrace, printedError);
      printedError = true;
    }
  
    return !printedError;
  }
  
  // Prints [error] to stderr, along with a preceding newline if anything else
  // has been printed to stderr.
  //
  // If [stackTrace] is passed, it is printed after the error.
  void _printError(String error, String? stackTrace, bool printedError) {
    var buffer = StringBuffer();
    if (printedError) buffer.writeln();
    buffer.write(error);
    if (stackTrace != null) {
      buffer.writeln();
      buffer.writeln();
      buffer.write(stackTrace);
    }
    printError(buffer);
  }
  