// Copyright 2019 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:io';

import 'package:meta/meta.dart';
import 'package:process/process.dart';

@immutable
class RunningProcessInfo {
  const RunningProcessInfo(this.pid, this.creationDate, this.commandLine)
      : assert(pid != null),
        assert(commandLine != null);

  final String commandLine;
  final String pid;
  final DateTime creationDate;

  @override
  bool operator ==(Object other) {
    return other is RunningProcessInfo &&
        other.pid == pid &&
        other.commandLine == commandLine &&
        other.creationDate == creationDate;
  }

  @override
  int get hashCode {
    // TODO(dnfield): Replace this when Object.hashValues lands.
    int hash = 17;
    if (pid != null) {
      hash = hash * 23 + pid.hashCode;
    }
    if (commandLine != null) {
      hash = hash * 23 + commandLine.hashCode;
    }
    if (creationDate != null) {
      hash = hash * 23 + creationDate.hashCode;
    }
    return hash;
  }

  @override
  String toString() {
    return 'RunningProcesses{pid: $pid, commandLine: $commandLine, creationDate: $creationDate}';
  }
}

Future<bool> killProcess(String pid, {ProcessManager processManager}) async {
  assert(pid != null, 'Must specify a pid to kill');
  processManager ??= const LocalProcessManager();
  ProcessResult result;
  if (Platform.isWindows) {
    result = await processManager.run(<String>[
      'taskkill.exe',
      '/pid',
      pid,
      '/f',
    ]);
  } else {
    result = await processManager.run(<String>[
      'kill',
      '-9',
      pid,
    ]);
  }
  return result.exitCode == 0;
}

Stream<RunningProcessInfo> getRunningProcesses({
  String processName,
  ProcessManager processManager,
}) {
  processManager ??= const LocalProcessManager();
  if (Platform.isWindows) {
    return windowsRunningProcesses(processName);
  }
  return posixRunningProcesses(processName, processManager);
}

@visibleForTesting
Stream<RunningProcessInfo> windowsRunningProcesses(String processName) async* {
  // PowerShell script to get the command line arguments and create time of
  // a process.
  // See: https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-process
  final String script = processName != null
      ? '"Get-CimInstance Win32_Process -Filter \\\"name=\'$processName\'\\\" | Select-Object ProcessId,CreationDate,CommandLine | Format-Table -AutoSize | Out-String -Width 4096"'
      : '"Get-CimInstance Win32_Process | Select-Object ProcessId,CreationDate,CommandLine | Format-Table -AutoSize | Out-String -Width 4096"';
  // Unfortunately, there doesn't seem to be a good way to get ProcessManager to
  // run this. May be a bug in Dart.
  // TODO(dnfield): fix this when https://github.com/dart-lang/sdk/issues/36175 is resolved.
  final ProcessResult result = await Process.run(
    'powershell -command $script',
    <String>[],
  );
  if (result.exitCode != 0) {
    print('Could not list processes!');
    print(result.stderr);
    print(result.stdout);
    return;
  }
  for (RunningProcessInfo info in processPowershellOutput(result.stdout)) {
    yield info;
  }
}

/// Parses the output of the PowerShell script from [windowsRunningProcesses].
///
/// E.g.:
/// ProcessId CreationDate          CommandLine
/// --------- ------------          -----------
///      2904 3/11/2019 11:01:54 AM "C:\Program Files\Android\Android Studio\jre\bin\java.exe" -Xmx1536M -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant -cp C:\Users\win1\.gradle\wrapper\dists\gradle-4.10.2-all\9fahxiiecdb76a5g3aw9oi8rv\gradle-4.10.2\lib\gradle-launcher-4.10.2.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 4.10.2
@visibleForTesting
Iterable<RunningProcessInfo> processPowershellOutput(String output) sync* {
  if (output == null) {
    return;
  }

  const int processIdHeaderSize = 'ProcessId'.length;
  const int creationDateHeaderStart = processIdHeaderSize + 1;
  int creationDateHeaderEnd;
  int commandLineHeaderStart;
  bool inTableBody = false;
  for (String line in output.split('\n')) {
    if (line.startsWith('ProcessId')) {
      commandLineHeaderStart = line.indexOf('CommandLine');
      creationDateHeaderEnd = commandLineHeaderStart - 1;
    }
    if (line.startsWith('--------- ------------')) {
      inTableBody = true;
      continue;
    }
    if (!inTableBody || line.isEmpty) {
      continue;
    }
    if (line.length < commandLineHeaderStart) {
      continue;
    }

    // 3/11/2019 11:01:54 AM
    // 12/11/2019 11:01:54 AM
    String rawTime = line.substring(
      creationDateHeaderStart,
      creationDateHeaderEnd,
    ).trim();

    if (rawTime[1] == '/') {
      rawTime = '0$rawTime';
    }
    if (rawTime[4] == '/') {
      rawTime = rawTime.substring(0, 3) + '0' + rawTime.substring(3);
    }
    final String year = rawTime.substring(6, 10);
    final String month = rawTime.substring(3, 5);
    final String day = rawTime.substring(0, 2);
    String time = rawTime.substring(11, 19);
    if (time[7] == ' ') {
      time = '0$time'.trim();
    }
    if (rawTime.endsWith('PM')) {
      final int hours = int.parse(time.substring(0, 2));
      time = '${hours + 12}${time.substring(2)}';
    }

    final String pid = line.substring(0, processIdHeaderSize).trim();
    final DateTime creationDate = DateTime.parse('$year-$month-${day}T$time');
    final String commandLine = line.substring(commandLineHeaderStart).trim();
    yield RunningProcessInfo(pid, creationDate, commandLine);
  }
}

@visibleForTesting
Stream<RunningProcessInfo> posixRunningProcesses(
  String processName,
  ProcessManager processManager,
) async* {
  // Cirrus is missing this in Linux for some reason.
  if (!processManager.canRun('ps')) {
    print('Cannot list processes on this system: `ps` not available.');
    return;
  }
  final ProcessResult result = await processManager.run(<String>[
    'ps',
    '-eo',
    'lstart,pid,command',
  ]);
  if (result.exitCode != 0) {
    print('Could not list processes!');
    print(result.stderr);
    print(result.stdout);
    return;
  }
  for (RunningProcessInfo info in processPsOutput(result.stdout, processName)) {
    yield info;
  }
}

/// Parses the output of the command in [posixRunningProcesses].
///
/// E.g.:
///
/// STARTED                        PID COMMAND
/// Sat Mar  9 20:12:47 2019         1 /sbin/launchd
/// Sat Mar  9 20:13:00 2019        49 /usr/sbin/syslogd
@visibleForTesting
Iterable<RunningProcessInfo> processPsOutput(
  String output,
  String processName,
) sync* {
  if (output == null) {
    return;
  }
  bool inTableBody = false;
  for (String line in output.split('\n')) {
    if (line.trim().startsWith('STARTED')) {
      inTableBody = true;
      continue;
    }
    if (!inTableBody || line.isEmpty) {
      continue;
    }

    if (processName != null && !line.contains(processName)) {
      continue;
    }
    if (line.length < 25) {
      continue;
    }

    // 'Sat Feb 16 02:29:55 2019'
    // 'Sat Mar  9 20:12:47 2019'
    const Map<String, String> months = <String, String>{
      'Jan': '01',
      'Feb': '02',
      'Mar': '03',
      'Apr': '04',
      'May': '05',
      'Jun': '06',
      'Jul': '07',
      'Aug': '08',
      'Sep': '09',
      'Oct': '10',
      'Nov': '11',
      'Dec': '12',
    };
    final String rawTime = line.substring(0, 24);

    final String year = rawTime.substring(20, 24);
    final String month = months[rawTime.substring(4, 7)];
    final String day = rawTime.substring(8, 10).replaceFirst(' ', '0');
    final String time = rawTime.substring(11, 19);

    final DateTime creationDate = DateTime.parse('$year-$month-${day}T$time');
    line = line.substring(24).trim();
    final int nextSpace = line.indexOf(' ');
    final String pid = line.substring(0, nextSpace);
    final String commandLine = line.substring(nextSpace + 1);
    yield RunningProcessInfo(pid, creationDate, commandLine);
  }
}
