// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This example shows how to send a bunch of jobs to ProcessPool for processing.
//
// This example program is actually pretty useful even if you don't use
// process_runner for your Dart project. It can speed up processing of a bunch
// of single-threaded CPU-intensive commands by a multple of the number of
// processor cores you have (modulo being disk/network bound, of course).

// @dart = 2.10

import 'dart:io';

import 'package:process_runner/process_runner.dart';

// This only works for escaped spaces and things in double or single quotes.
// This is just an example, modify to meet your own requirements.
List<String> splitIntoArgs(String args) {
  bool inQuote = false;
  bool inEscape = false;
  String quoteMatch = '';
  final List<String> result = <String>[];
  final List<String> currentArg = <String>[];
  for (int i = 0; i < args.length; ++i) {
    final String char = args[i];
    if (inEscape) {
      switch (char) {
        case 'n':
          currentArg.add('\n');
          break;
        case 't':
          currentArg.add('\t');
          break;
        case 'r':
          currentArg.add('\r');
          break;
        case 'b':
          currentArg.add('\b');
          break;
        default:
          currentArg.add(char);
          break;
      }
      inEscape = false;
      continue;
    }
    if (char == ' ' && !inQuote) {
      result.add(currentArg.join(''));
      currentArg.clear();
      continue;
    }
    if (char == r'\') {
      inEscape = true;
      continue;
    }
    if (inQuote) {
      if (char == quoteMatch) {
        inQuote = false;
        quoteMatch = '';
      } else {
        currentArg.add(char);
      }
      continue;
    }
    if (char == '"' || char == '"') {
      inQuote = !inQuote;
      quoteMatch = args[i];
      continue;
    }
    currentArg.add(char);
  }
  if (currentArg.isNotEmpty) {
    result.add(currentArg.join(''));
  }
  return result;
}

String usage() {
  return '''
main.dart [flags]
    --[no-]help           Print help.
    --[no-]report         Print progress on the jobs while running.
-w, --workers             Specify the number of workers jobs to run simultanously. Defaults to the number of processors on the machine.
-d, --workingDirectory    Specify the working directory to run on
                          (defaults to ".")
-c, --cmd                 Specify a command to add to the commands to be run. Entire command must be quoted by the shell. Commands specified with this option run before those specified with --cmdFile
-f, --file                Specify the name of a file to read commands from, one per line, as they would appear on the command line, with spaces escaped or quoted. Specify "-" to read from stdin.
                          (defaults to "-")
''';
}

String? findOption(String option, List<String> args) {
  for (int i = 0; i < args.length - 1; ++i) {
    if (args[i] == option) {
      return args[i + 1];
    }
  }
  return null;
}

Iterable<String> findAllOptions(String option, List<String> args) sync* {
  for (int i = 0; i < args.length - 1; ++i) {
    if (args[i] == option) {
      yield args[i + 1];
    }
  }
}

Future<void> main(List<String> args) async {
  // Parse args without ArgParser until ArgParser is null-safe.
  if (args.contains('--help')) {
    print('main.dart [flags]');
    print(usage());
    exit(0);
  }

  final bool printReport = args.contains('--report');
  // If the numWorkers is set to null, then the ProcessPool will automatically
  // select the number of processes based on how many CPU cores the machine has.
  final int? numWorkers = int.tryParse(findOption('workers', args) ?? '');
  final Directory workingDirectory = Directory(findOption('workingDirectory', args) ?? '.');
  final List<String> cmds = findAllOptions('cmd', args).toList();

  // Collect the commands to be run from the command file.
  final String commandFile = findOption('file', args) ?? '-';
  List<String> fileCommands = <String>[];
  // Read from stdin if the --file option is set to '-'.
  if (commandFile == '-') {
    String? line = stdin.readLineSync();
    while (line != null) {
      fileCommands.add(line);
      line = stdin.readLineSync();
    }
  } else {
    // Read the commands from a file.
    final File cmdFile = File(commandFile);
    if (!cmdFile.existsSync()) {
      print('Command file "$commandFile" doesn\'t exist.');
      exit(1);
    }
    fileCommands = cmdFile.readAsLinesSync();
  }

  // Collect all the commands, both from the input file, and from the command
  // line. The command line commands come first (although they could all be
  // executed simultaneously, depending on the number of workers, and number of
  // commands).
  final List<String> commands = <String>[
    ...cmds,
    ...fileCommands,
  ];

  // Split each command entry into a list of strings, taking into account some
  // simple quoting and escaping.
  final List<List<String>> splitCommands = commands.map<List<String>>(splitIntoArgs).toList();

  final ProcessPool pool = ProcessPool(
    numWorkers: numWorkers,
    printReport: printReport ? ProcessPool.defaultPrintReport : null,
  );
  final List<WorkerJob> jobs = splitCommands.map<WorkerJob>((List<String> command) {
    return WorkerJob(command, workingDirectory: workingDirectory);
  }).toList();
  await for (final WorkerJob done in pool.startWorkers(jobs)) {
    if (printReport) {
      print('\nFinished job ${done.name}');
    }
    stdout.write(done.result!.stdout);
  }
}
