// 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.

import 'dart:async';
import 'dart:convert' show Encoding;
import 'dart:io' show Directory, Platform, stdout, SystemEncoding, stderr, ProcessStartMode;

import 'package:async/async.dart' show StreamGroup;

import 'process_runner.dart';

/// Base class for all job types.
///
/// Defines an API for getting at the sub-tasks of a job, and for getting the
/// number of sub-tasks.
abstract class Job {
  /// Return the stream of sub-tasks for this job.
  ///
  /// These tasks will be executed in order, but in parallel with tasks from
  /// other jobs.
  Stream<WorkerJob> get tasks;

  /// Return the number of tasks in this job.
  ///
  /// May be calculated asynchronously, but must complete before the first
  /// task will be started.
  Future<int> get numTasks;
}

/// A class that represents a single task to be performed by a [ProcessPool].
///
/// Create a list of these to pass to [ProcessPool.startWorkers] or
/// [ProcessPool.runToCompletion].
class WorkerJob extends Job {
  WorkerJob(
    this.command, {
    String? name,
    this.workingDirectory,
    this.printOutput = false,
    this.stdin,
    this.stdinRaw,
    this.failOk = true,
    this.runInShell = false,
  }) : name = name ?? command.join(' ');

  /// The name of the job.
  ///
  /// Defaults to the args joined by a space.
  final String name;

  /// The name and arguments for the process, including the command name as
  /// command[0].
  final List<String> command;

  /// The working directory that the command should be executed in.
  final Directory? workingDirectory;

  /// If set, the stream to read the stdin for this process from.
  ///
  /// It will be encoded using the [ProcessPool.encoding] before being sent to
  /// the process.
  ///
  /// If both [stdin] and [stdinRaw] are set, only [stdinRaw] will be used.
  final Stream<String>? stdin;

  /// If set, the stream to read the raw stdin for this process from.
  ///
  /// It will be used directly, and not encoded (as [stdin] would be).
  ///
  /// If both [stdin] and [stdinRaw] are set, only [stdinRaw] will be used.
  final Stream<List<int>>? stdinRaw;

  /// Whether or not this command should print it's stdout when it runs.
  final bool printOutput;

  /// Whether or not failure of this job should throw an exception.
  ///
  /// If `failOk` is false, and this job fails (returns a non-zero exit code, or
  /// otherwise fails to start), then a [ProcessRunnerException] will be thrown
  /// containing the details.
  ///
  /// Defaults to true, since the [result] will contain the exit code.
  final bool failOk;

  /// If set to true, the process will run be spawned through a system shell.
  ///
  /// Running in a shell is generally not recommended, as it provides worse
  /// performance, and some security risk, but is sometimes necessary for
  /// accessing the shell environment. Shell command line expansion and
  /// interpolation is not performed on the commands, but you can execute shell
  /// builtins. Use the shell builtin "eval" (on Unix systems) if you want to
  /// execute shell commands with expansion.
  ///
  /// On Linux and OS X, `/bin/sh` is used, while on Windows,
  /// `%WINDIR%\system32\cmd.exe` is used.
  ///
  /// Defaults to false.
  final bool runInShell;

  /// Once the job is complete, this contains the result of the job.
  ///
  /// The [stderr], [stdout], and [output] accessors will decode their raw
  /// equivalents using the [ProcessRunner.decoder] that is set on the process
  /// runner for the pool that ran this job.
  ///
  /// If no process runner is supplied to the pool, then the decoder will be the
  /// same as the [ProcessPool.encoding] that was set on the pool.
  ///
  /// The initial value of this field is [ProcessRunnerResult.emptySuccess],
  /// and is updated when the job is complete.
  ProcessRunnerResult result = ProcessRunnerResult.emptySuccess;

  /// Once the job is complete, if it had an exception while running, this
  /// member contains the exception.
  Exception? exception;

  @override
  Stream<WorkerJob> get tasks async* {
    yield this;
  }

  @override
  Future<int> get numTasks async => 1;

  @override
  String toString() => command.join(' ');
}

class WorkerJobGroup extends Job {
  WorkerJobGroup(this.workers);

  final Iterable<WorkerJob> workers;

  @override
  Stream<WorkerJob> get tasks async* {
    yield* StreamGroup.merge(workers.map((WorkerJob worker) => worker.tasks));
  }

  @override
  Future<int> get numTasks async {
    int numTasks = 0;
    for (final WorkerJob job in workers) {
      numTasks += await job.numTasks;
    }
    return numTasks;
  }
}

/// The type of the reporting function for [ProcessPool.printReport].
typedef ProcessPoolProgressReporter = void Function(
  int totalJobs,
  int completed,
  int inProgress,
  int pending,
  int groupsPending,
  int failed,
);

/// A pool of worker processes that will keep [numWorkers] busy until all of the
/// (presumably single-threaded) processes are finished.
class ProcessPool {
  ProcessPool({
    int? numWorkers,
    ProcessRunner? processRunner,
    this.printReport = defaultPrintReport,
    this.encoding = const SystemEncoding(),
  })  : processRunner = processRunner ?? ProcessRunner(decoder: encoding),
        numWorkers = numWorkers ?? Platform.numberOfProcessors;

  /// A function to be called periodically to update the progress on the pool.
  ///
  /// May be set to null if no progress report is desired.
  ///
  /// Defaults to [defaultProgressReport], which prints the progress report to
  /// stdout.
  final ProcessPoolProgressReporter? printReport;

  /// The decoder to use for decoding the stdout, stderr, and output of a
  /// process, and encoding the stdin from the job.
  ///
  /// Defaults to an instance of [SystemEncoding].
  final Encoding encoding;

  /// The process runner to use when running the jobs in the pool.
  ///
  /// Setting this allows for configuration of the process runnner.
  ///
  /// Be default, a default-constructed [ProcessRunner] is used.
  final ProcessRunner processRunner;

  /// The number of workers to use for this pool.
  ///
  /// Defaults to the number of processors the machine has.
  final int numWorkers;

  /// Returns the number of jobs currently in progress.
  int get inProgressJobs => _inProgressTasks;
  int _inProgressTasks = 0;

  /// Returns the number of jobs that have been completed
  int get completedJobs => _completedTasks.length;

  /// Returns the number of jobs that are pending.
  int get pendingJobs => _pendingTasksCount;

  /// Returns the number of groups that are pending.
  int get pendingTaskGroups => _pendingJobGroups.length;

  /// Returns the number of jobs that have failed so far.
  int get failedJobs => _failedTasks.length;

  /// Returns the total number of jobs that have been given to this pool.
  int get totalJobs {
    return _completedTasks.length + _inProgressTasks + _pendingTasksCount + _failedTasks.length;
  }

  int _pendingTasksCount = 0;

  final List<Job> _pendingJobGroups = <Job>[];
  final List<WorkerJob> _failedTasks = <WorkerJob>[];
  final List<WorkerJob> _completedTasks = <WorkerJob>[];

  void _printReportIfNeeded() {
    if (printReport == null) {
      return;
    }
    printReport?.call(totalJobs, _completedTasks.length, _inProgressTasks, _pendingTasksCount,
        _pendingJobGroups.length, _failedTasks.length);
  }

  static String defaultReportToString(
    int total,
    int completed,
    int inProgress,
    int pending,
    int groupsPending,
    int failed,
  ) {
    final String percent =
        total == 0 ? '100' : ((100 * (completed + failed)) ~/ total).toString().padLeft(3);
    final String completedStr = completed.toString().padLeft(3);
    final String totalStr = total.toString().padRight(3);
    final String inProgressStr = inProgress.toString().padLeft(2);
    final String pendingStr = pending.toString().padLeft(3);
    final String pendingGroupsStr = groupsPending.toString().padLeft(2);
    final String failedStr = failed.toString().padLeft(3);
    return 'Jobs: $percent% done, $completedStr/$totalStr completed, $inProgressStr in progress, $pendingStr pending (in $pendingGroupsStr groups), $failedStr failed.    \r';
  }

  /// The default report printing function, if one is not supplied.
  static void defaultPrintReport(
    int total,
    int completed,
    int inProgress,
    int pending,
    int groupsPending,
    int failed,
  ) {
    stdout
        .write(defaultReportToString(total, completed, inProgress, pending, groupsPending, failed));
  }

  Stream<WorkerJob> _performTasks(Job job) async* {
    await for (final WorkerJob job in job.tasks) {
      try {
        _inProgressTasks++;
        _printReportIfNeeded();
        job.result = await processRunner.runProcess(
          job.command,
          workingDirectory: job.workingDirectory ?? processRunner.defaultWorkingDirectory,
          printOutput: job.printOutput,
          stdin: job.stdinRaw ?? encoding.encoder.bind(job.stdin ?? const Stream<String>.empty()),
          // Starting process pool jobs in any other mode makes no sense: they
          // would all just be immediately started and bring the machine to its
          // knees.
          startMode: ProcessStartMode.normal,
          runInShell: job.runInShell,
          failOk: false, // Must be false so that we can catch the exception below.
        );
        _completedTasks.add(job);
      } on ProcessRunnerException catch (e) {
        job.result = e.result ?? ProcessRunnerResult.failed;
        job.exception = e;
        _failedTasks.add(job);
        if (!job.failOk) {
          rethrow;
        }
      } finally {
        _inProgressTasks--;
        _printReportIfNeeded();
        yield job;
      }
    }
  }

  Stream<WorkerJob> _startWorker() async* {
    while (_pendingJobGroups.isNotEmpty) {
      final Job newJob = _pendingJobGroups.removeAt(0);
      _pendingTasksCount = 0;
      final List<Job> jobs = _pendingJobGroups.toList();
      for (final Job job in jobs) {
        _pendingTasksCount += await job.numTasks;
      }
      _printReportIfNeeded();
      yield* _performTasks(newJob);
    }
  }

  /// Runs all of the jobs to completion, and returns a list of completed jobs
  /// when all have been completed.
  ///
  /// To listen to jobs as they are completed, use [startWorkers] instead.
  Future<List<WorkerJob>> runToCompletion(List<Job> jobs) async {
    final List<WorkerJob> results = <WorkerJob>[];
    await startWorkers(jobs).forEach(results.add);
    return results;
  }

  /// Runs the `jobs` in parallel, with at most [numWorkers] jobs running
  /// simultaneously.
  ///
  /// If the supplied job is a [WorkerJobGroup], then the jobs in the task
  /// group will be run so that the tasks are executed in order (but still in
  /// parallel with other jobs).
  ///
  /// Returns the the jobs in a [Stream] as they are completed.
  Stream<WorkerJob> startWorkers(Iterable<Job> jobs) async* {
    assert(_inProgressTasks == 0);
    _failedTasks.clear();
    _completedTasks.clear();
    _pendingTasksCount = 0;
    _pendingJobGroups.clear();
    if (jobs.isEmpty) {
      return;
    }
    _pendingJobGroups.addAll(jobs);
    for (final Job job in jobs) {
      _pendingTasksCount += await job.numTasks;
    }
    _printReportIfNeeded();
    final List<Stream<WorkerJob>> streams = <Stream<WorkerJob>>[];
    for (int i = 0; i < numWorkers; ++i) {
      if (_pendingJobGroups.isEmpty) {
        break;
      }
      streams.add(_startWorker());
    }
    await for (final WorkerJob job in StreamGroup.merge<WorkerJob>(streams)) {
      yield job;
    }
    assert(_inProgressTasks == 0);
    assert(_pendingJobGroups.isEmpty);
    return;
  }
}
