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

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

Future<void> main(List<String> args) async {
  final ArgParser 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 bool quiet = options[_kQuietFlag]! as bool;
  final bool printStderr = !quiet && options[_kPrintStderrFlag]! as bool;
  final bool printStdout = !quiet && options[_kPrintStdoutFlag]! as bool;
  final bool printReport = options[_kReportFlag]! as bool;
  final bool runInShell = options[_kRunInShellFlag]! as bool;
  final bool failOk = options[_kAllowFailureFlag]! as bool;

  // Collect the commands to be run from the command file(s).
  final List<String>? 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 List<List<String>> fileCommands = getCommandsFromFiles(commandFiles);

  final List<String> 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 List<List<String>> splitCommands =
      collectedCommands.map<List<String>>((String command) => splitIntoArgs(command)).toList();

  // Collect the commands to be run from the group file(s).
  final List<List<String>> 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 List<List<List<String>>> 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 int? numWorkers = int.tryParse(options[_kJobsOption] as String? ?? '');
  final Directory workingDirectory =
      Directory((options[_kWorkingDirectoryOption] as String?) ?? '.');

  final ProcessPool pool = ProcessPool(
    numWorkers: numWorkers,
    printReport: printReport ? stderrPrintReport : null,
  );
  final Iterable<WorkerJobGroup> 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 Iterable<WorkerJob> parallelJobs =
      splitCommands.map<WorkerJob>((List<String> command) => WorkerJob(
            command,
            workingDirectory: workingDirectory,
            runInShell: runInShell,
            failOk: failOk,
          ));
  final Iterable<Job> jobs = parallelJobs.cast<Job>().followedBy(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 List<List<String>> fileCommands = <List<String>>[];
  if (commandFiles != null) {
    bool sawStdinAlready = false;
    for (final String 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;
        String? line = stdin.readLineSync();
        final List<String> commands = <String>[];
        while (line != null) {
          commands.add(line);
          line = stdin.readLineSync();
        }
        fileCommands.add(commands);
      } 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.add(cmdFile.readAsLinesSync());
      }
    }
  }
  return fileCommands;
}
