// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. 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:convert';
import 'dart:io' show ProcessStartMode, systemEncoding;

import 'manifest_entry.dart';

/// Gets a `ProcessStartMode` value by its string name.
ProcessStartMode _getProcessStartMode(String value) {
  if (value != null) {
    for (ProcessStartMode mode in ProcessStartMode.values) {
      if (mode.toString() == value) {
        return mode;
      }
    }
    throw FormatException('Invalid value for mode: $value');
  }
  return null;
}

/// Gets an `Encoding` instance by the encoding name.
Encoding _getEncoding(String encoding) {
  if (encoding == 'system') {
    return systemEncoding;
  } else if (encoding != null) {
    return Encoding.getByName(encoding);
  }
  return null;
}

/// An entry in the process invocation manifest for running an executable.
class RunManifestEntry extends ManifestEntry {
  /// Creates a new manifest entry with the given properties.
  RunManifestEntry({
    this.pid,
    this.basename,
    this.command,
    this.workingDirectory,
    this.environment,
    this.includeParentEnvironment,
    this.runInShell,
    this.mode,
    this.stdoutEncoding,
    this.stderrEncoding,
    this.exitCode,
  });

  /// Creates a new manifest entry populated with the specified JSON [data].
  ///
  /// If any required fields are missing from the JSON data, this will throw
  /// a [FormatException].
  factory RunManifestEntry.fromJson(Map<String, dynamic> data) {
    checkRequiredField(data, 'pid');
    checkRequiredField(data, 'basename');
    checkRequiredField(data, 'command');
    RunManifestEntry entry = RunManifestEntry(
      pid: data['pid'] as int,
      basename: data['basename'] as String,
      command: (data['command'] as List<dynamic>)?.cast<String>(),
      workingDirectory: data['workingDirectory'] as String,
      environment: (data['environment'] as Map<dynamic, dynamic>)
          ?.cast<String, String>(),
      includeParentEnvironment: data['includeParentEnvironment'] as bool,
      runInShell: data['runInShell'] as bool,
      mode: _getProcessStartMode(data['mode'] as String),
      stdoutEncoding: _getEncoding(data['stdoutEncoding'] as String),
      stderrEncoding: _getEncoding(data['stderrEncoding'] as String),
      exitCode: data['exitCode'] as int,
    );
    entry.daemon = data['daemon'] as bool;
    entry.notResponding = data['notResponding'] as bool;
    return entry;
  }

  @override
  final String type = 'run';

  /// The process id.
  final int pid;

  /// The base file name for this entry. `stdout` and `stderr` files for this
  /// process will be serialized in the recording directory as
  /// `$basename.stdout` and `$basename.stderr`, respectively.
  final String basename;

  /// The command that was run. The first element is the executable, and the
  /// remaining elements are the arguments to the executable.
  final List<String> command;

  /// The process' working directory when it was spawned.
  final String workingDirectory;

  /// The environment variables that were passed to the process.
  final Map<String, String> environment;

  /// Whether the invoker's environment was made available to the process.
  final bool includeParentEnvironment;

  /// Whether the process was spawned through a system shell.
  final bool runInShell;

  /// The mode with which the process was spawned.
  final ProcessStartMode mode;

  /// The encoding used for the `stdout` of the process.
  final Encoding stdoutEncoding;

  /// The encoding used for the `stderr` of the process.
  final Encoding stderrEncoding;

  /// The exit code of the process.
  int exitCode;

  /// The executable that was invoked.
  String get executable => command.first;

  /// The arguments that were passed to [executable].
  List<String> get arguments => command.skip(1).toList();

  /// Indicates that the process is a daemon.
  bool get daemon => _daemon;
  bool _daemon = false;
  set daemon(bool value) => _daemon = value ?? false;

  /// Indicates that the process did not respond to `SIGTERM`.
  bool get notResponding => _notResponding;
  bool _notResponding = false;
  set notResponding(bool value) => _notResponding = value ?? false;

  /// Returns a JSON-encodable representation of this manifest entry.
  @override
  Map<String, dynamic> toJson() => JsonBuilder()
      .add('pid', pid)
      .add('basename', basename)
      .add('command', command)
      .add('workingDirectory', workingDirectory)
      .add('environment', environment)
      .add('includeParentEnvironment', includeParentEnvironment)
      .add('runInShell', runInShell)
      .add('mode', mode, () => mode.toString())
      .add('stdoutEncoding', stdoutEncoding, () => stdoutEncoding.name)
      .add('stderrEncoding', stderrEncoding, () => stderrEncoding.name)
      .add('daemon', daemon)
      .add('notResponding', notResponding)
      .add('exitCode', exitCode)
      .entry;
}
