// 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 multiple of the number of
// processor cores you have (modulo being disk/network bound, of course).

import 'dart:io';

import 'package:args/args.dart';
import 'package:process_runner/process_runner.dart';

const String _kHelpFlag = 'help';
const String _kQuietFlag = 'quiet';
const String _kReportFlag = 'report';
const String _kPrintStdoutFlag = 'stdout';
const String _kPrintStderrFlag = 'stderr';
const String _kRunInShellFlag = 'run-in-shell';
const String _kAllowFailureFlag = 'fail-ok';
const List<String> _kFlags = <String>[
  _kHelpFlag,
  _kQuietFlag,
  _kReportFlag,
  _kPrintStdoutFlag,
  _kPrintStderrFlag,
  _kRunInShellFlag,
];
const String _kJobsOption = 'jobs';
const String _kWorkingDirectoryOption = 'working-directory';
const String _kCommandOption = 'command';
const String _kSourceOption = 'source';
const String _kGroupOption = 'group';
const String _kAppName = 'process_runner';

// 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) {
  var inQuote = false;
  var inEscape = false;
  var quoteMatch = '';
  final result = <String>[];
  final currentArg = <String>[];
  for (var i = 0; i < args.length; ++i) {
    final 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;
}

// Print reports to stderr, to avoid polluting any stdout from the jobs.
void stderrPrintReport(
  int total,
  int completed,
  int inProgress,
  int pending,
  int failed,
) {
  stderr.write(ProcessPool.defaultReportToString(
      total, completed, inProgress, pending, failed));
}

Future<void> main(List<String> args) async {
  final parser = ArgParser(usageLineLength: 80);
  parser.addFlag(
    _kHelpFlag,
    abbr: 'h',
    defaultsTo: false,
    negatable: false,
    help: 'Print help for $_kAppName.',
  );
  parser.addFlag(
    _kQuietFlag,
    abbr: 'q',
    defaultsTo: false,
    negatable: false,
    help: 'Silences the stderr and stdout output of the commands. This '
        'is a shorthand for "--no-$_kPrintStdoutFlag --no-$_kPrintStderrFlag".',
  );
  parser.addFlag(
    _kReportFlag,
    abbr: 'r',
    defaultsTo: false,
    negatable: false,
    help: 'Print progress on the jobs to stderr while running.',
  );
  parser.addFlag(
    _kPrintStdoutFlag,
    defaultsTo: true,
    help: 'Prints the stdout output of the commands to stdout in the order '
        'they complete. Will not interleave lines from separate processes. Has '
        'no effect if --$_kQuietFlag is specified.',
  );
  parser.addFlag(
    _kPrintStderrFlag,
    defaultsTo: true,
    help: 'Prints the stderr output of the commands to stderr in the order '
        'they complete. Will not interleave lines from separate processes. Has '
        'no effect if --$_kQuietFlag is specified',
  );
  parser.addFlag(
    _kRunInShellFlag,
    defaultsTo: false,
    negatable: false,
    help: 'Run the commands in a subshell.',
  );
  parser.addFlag(
    _kAllowFailureFlag,
    defaultsTo: false,
    help:
        'If set, allows continuing execution of the remaining commands even if '
        'one fails to execute. If not set, ("--no-$_kAllowFailureFlag") then '
        'process will just exit with a non-zero code at completion if there '
        'were any jobs that failed.',
  );
  parser.addOption(
    _kJobsOption,
    abbr: 'j',
    help: 'Specify the number of worker jobs to run simultaneously. Defaults '
        'to the number of processor cores on the machine (which is '
        '${Platform.numberOfProcessors} on this machine).',
  );
  parser.addOption(
    _kWorkingDirectoryOption,
    defaultsTo: '.',
    help: 'Specify the working directory to run in.',
  );
  parser.addMultiOption(
    _kCommandOption,
    abbr: 'c',
    help: 'Specify a command to add to the commands to be run. Commands '
        'specified with this option run before those specified with '
        '--$_kSourceOption. Be sure to quote arguments to --$_kCommandOption '
        'properly on the command line.',
  );
  parser.addMultiOption(
    _kGroupOption,
    abbr: 'g',
    defaultsTo: <String>[],
    help: 'Specify the name of a file to read grouped commands from, one per '
        'line, as they would appear on the command line, with spaces escaped '
        'or quoted. More than one --$_kGroupOption argument may be specified, '
        'and each file will be run as a separate job group with the commands '
        'in each group run in the order specified in the file, but in parallel '
        'with other groups.',
  );
  parser.addMultiOption(
    _kSourceOption,
    abbr: 's',
    defaultsTo: <String>[],
    help: '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 "--$_kSourceOption -" to read from stdin. More than '
        'one --$_kSourceOption argument may be specified, and they will be '
        'run as separate tasks in parallel. The stdin '
        '("--$_kSourceOption -") argument may only be specified once.',
  );

  late ArgResults options;
  try {
    options = parser.parse(args);
  } on FormatException catch (e) {
    stderr.writeln('Argument Error: ${e.message}');
    stderr.writeln(parser.usage);
    exitCode = 1;
    return;
  }

  if (options[_kHelpFlag] as bool) {
    print(
      '$_kAppName [--${_kFlags.join('] [--')}] '
      '[--$_kWorkingDirectoryOption=<working directory>] '
      '[--$_kJobsOption=<num_worker_jobs>] '
      '[--$_kCommandOption="command" ...] '
      '[--$_kGroupOption=<file> ...] '
      '[--$_kSourceOption=<file|"-"> ...]:',
    );

    print(parser.usage);
    exitCode = 0;
    return;
  }

  final quiet = options[_kQuietFlag]! as bool;
  final printStderr = !quiet && options[_kPrintStderrFlag]! as bool;
  final printStdout = !quiet && options[_kPrintStdoutFlag]! as bool;
  final printReport = options[_kReportFlag]! as bool;
  final runInShell = options[_kRunInShellFlag]! as bool;
  final failOk = options[_kAllowFailureFlag]! as bool;

  // Collect the commands to be run from the command file(s).
  final commandFiles = options[_kSourceOption] as List<String>?;
  // Collect all the commands, both from input files, and from the command
  // line. The command line commands are run first (although they could all
  // potentially be executed simultaneously, depending on the number of workers,
  // and number of commands).
  final fileCommands = getCommandsFromFiles(commandFiles);

  final collectedCommands = <String>[
    if (options[_kCommandOption] != null)
      ...options[_kCommandOption]! as List<String>,
  ];
  fileCommands.forEach(collectedCommands
      .addAll); // Flatten the groups so they can be run in parallel.

  final splitCommands =
      collectedCommands.map<List<String>>(splitIntoArgs).toList();

  // Collect the commands to be run from the group file(s).
  final groupCommands = getCommandsFromFiles(
      options[_kGroupOption] as List<String>,
      allowStdin: false);

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

  // 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 numWorkers = int.tryParse(options[_kJobsOption] as String? ?? '');
  final workingDirectory =
      Directory((options[_kWorkingDirectoryOption] as String?) ?? '.');

  final pool = ProcessPool(
    numWorkers: numWorkers,
    printReport: printReport ? stderrPrintReport : null,
  );
  final groupedJobs =
      splitGroupCommands.map<WorkerJobGroup>((List<List<String>> group) {
    return WorkerJobGroup(group
        .map<WorkerJob>((List<String> command) => WorkerJob(
              command,
              workingDirectory: workingDirectory,
              runInShell: runInShell,
              failOk: failOk,
            ))
        .toList());
  });
  final parallelJobs =
      splitCommands.map<WorkerJob>((List<String> command) => WorkerJob(
            command,
            workingDirectory: workingDirectory,
            runInShell: runInShell,
            failOk: failOk,
          ));
  final Iterable<DependentJob> jobs = <DependentJob>[
    ...parallelJobs,
    ...groupedJobs
  ];
  try {
    await for (final WorkerJob done in pool.startWorkers(jobs)) {
      if (printStdout) {
        stdout.write(done.result.stdout);
      }
      if (printStderr) {
        stderr.write(done.result.stderr);
      }
    }
  } on ProcessRunnerException catch (e) {
    if (!failOk) {
      stderr.writeln('$_kAppName execution failed: $e');
      exitCode = e.exitCode;
      return;
    }
  }

  // Return non-zero exit code if there were jobs that failed.
  exitCode = pool.failedJobs != 0 ? 1 : 0;
}

List<List<String>> getCommandsFromFiles(List<String>? commandFiles,
    {bool allowStdin = false}) {
  final fileCommands = <List<String>>[];
  if (commandFiles != null) {
    var sawStdinAlready = false;
    for (final commandFile in commandFiles) {
      // Read from stdin if the --file option is set to '-'.
      if (allowStdin && commandFile == '-') {
        if (sawStdinAlready) {
          stderr.writeln('ERROR: The stdin can only be specified once with '
              '"--$_kSourceOption -"');
          exitCode = 1;
          return <List<String>>[];
        }
        sawStdinAlready = true;
        var line = stdin.readLineSync();
        final commands = <String>[];
        while (line != null) {
          commands.add(line);
          line = stdin.readLineSync();
        }
        fileCommands.add(commands);
      } else {
        // Read the commands from a file.
        final cmdFile = File(commandFile);
        if (!cmdFile.existsSync()) {
          print('''Command file "$commandFile" doesn't exist.''');
          exit(1);
        }
        fileCommands.add(cmdFile.readAsLinesSync());
      }
    }
  }
  return fileCommands;
}
