// Copyright (c) 2018, 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.

library dartdoc.tool_runner;

import 'dart:async';
import 'dart:io';

import 'package:dartdoc/src/io_utils.dart';
import 'package:path/path.dart' as pathLib;
import 'dartdoc_options.dart';

typedef ToolErrorCallback = void Function(String message);
typedef FakeResultCallback = String Function(String tool,
    {List<String> args, String content});

/// Set a ceiling on how many tool instances can be in progress at once,
/// limiting both parallelization and the number of open temporary files.
final MultiFutureTracker _toolTracker = new MultiFutureTracker(4);

/// Can be called when the ToolRunner is no longer needed.
///
/// This will remove any temporary files created by the tool runner.
class ToolTempFileTracker {
  final Directory temporaryDirectory;

  ToolTempFileTracker._()
      : temporaryDirectory =
            Directory.systemTemp.createTempSync('dartdoc_tools_');

  static ToolTempFileTracker _instance;
  static ToolTempFileTracker get instance =>
      _instance ??= ToolTempFileTracker._();

  int _temporaryFileCount = 0;
  Future<File> createTemporaryFile() async {
    _temporaryFileCount++;
    File tempFile = new File(pathLib.join(
        temporaryDirectory.absolute.path, 'input_$_temporaryFileCount'));
    await tempFile.create(recursive: true);
    return tempFile;
  }

  /// Call once no more files are to be created.
  Future<void> dispose() async {
    if (temporaryDirectory.existsSync()) {
      return temporaryDirectory.delete(recursive: true);
    }
  }
}

/// A helper class for running external tools.
class ToolRunner {
  /// Creates a new ToolRunner.
  ///
  /// Takes a [toolConfiguration] that describes all of the available tools.
  /// An optional `errorCallback` will be called for each error message
  /// generated by the tool.
  ToolRunner(this.toolConfiguration);

  final ToolConfiguration toolConfiguration;

  void _runSetup(
      String name,
      ToolDefinition tool,
      Map<String, String> environment,
      ToolErrorCallback toolErrorCallback) async {
    bool isDartSetup = ToolDefinition.isDartExecutable(tool.setupCommand[0]);
    var args = tool.setupCommand.toList();
    String commandPath;

    if (isDartSetup) {
      commandPath = Platform.resolvedExecutable;
    } else {
      commandPath = args.removeAt(0);
    }
    await _runProcess(
        name, '', commandPath, args, environment, toolErrorCallback);
    tool.setupComplete = true;
  }

  Future<String> _runProcess(
      String name,
      String content,
      String commandPath,
      List<String> args,
      Map<String, String> environment,
      ToolErrorCallback toolErrorCallback) async {
    String commandString() => ([commandPath] + args).join(' ');
    try {
      ProcessResult result =
          await Process.run(commandPath, args, environment: environment);
      if (result.exitCode != 0) {
        toolErrorCallback('Tool "$name" returned non-zero exit code '
            '(${result.exitCode}) when run as '
            '"${commandString()}" from ${Directory.current}\n'
            'Input to $name was:\n'
            '$content\n'
            'Stderr output was:\n${result.stderr}\n');
        return '';
      } else {
        return result.stdout;
      }
    } on ProcessException catch (exception) {
      toolErrorCallback('Failed to run tool "$name" as '
          '"${commandString()}": $exception\n'
          'Input to $name was:\n'
          '$content');
      return '';
    }
  }

  /// Run a tool.  The name of the tool is the first argument in the [args].
  /// The content to be sent to to the tool is given in the optional [content],
  /// and the stdout of the tool is returned.
  ///
  /// The [args] must not be null, and it must have at least one member (the name
  /// of the tool).
  Future<String> run(List<String> args, ToolErrorCallback toolErrorCallback,
      {String content, Map<String, String> environment}) async {
    Future runner;
    // Prevent too many tools from running simultaneously.
    await _toolTracker.addFutureFromClosure(() {
      runner = _run(args, toolErrorCallback,
          content: content, environment: environment);
      return runner;
    });
    return runner;
  }

  Future<String> _run(List<String> args, ToolErrorCallback toolErrorCallback,
      {String content, Map<String, String> environment}) async {
    assert(args != null);
    assert(args.isNotEmpty);
    content ??= '';
    environment ??= <String, String>{};
    var tool = args.removeAt(0);
    if (!toolConfiguration.tools.containsKey(tool)) {
      toolErrorCallback(
          'Unable to find definition for tool "$tool" in tool map. '
          'Did you add it to dartdoc_options.yaml?');
      return '';
    }
    ToolDefinition toolDefinition = toolConfiguration.tools[tool];
    var toolArgs = toolDefinition.command;
    // Ideally, we would just be able to send the input text into stdin, but
    // there's no way to do that synchronously, and converting dartdoc to an
    // async model of execution is a huge amount of work. Using dart:cli's
    // waitFor feels like a hack (and requires a similar amount of work anyhow
    // to fix order of execution issues). So, instead, we have the tool take a
    // filename as part of its arguments, and write the input to a temporary
    // file before running the tool synchronously.

    // Write the content to a temp file.
    var tmpFile = await ToolTempFileTracker.instance.createTemporaryFile();
    await tmpFile.writeAsString(content);

    // Substitute the temp filename for the "$INPUT" token, and all of the other
    // environment variables. Variables are allowed to either be in $(VAR) form,
    // or $VAR form.
    var envWithInput = {
      'INPUT': tmpFile.absolute.path,
      'TOOL_COMMAND': toolDefinition.command[0]
    }..addAll(environment);
    if (toolDefinition is DartToolDefinition) {
      // Put the original command path into the environment, because when it
      // runs as a snapshot, Platform.script (inside the tool script) refers to
      // the snapshot, and not the original script.  This way at least, the
      // script writer can use this instead of Platform.script if they want to
      // find out where their script was coming from as an absolute path on the
      // filesystem.
      envWithInput['DART_SNAPSHOT_CACHE'] =
          SnapshotCache.instance.snapshotCache.absolute.path;
      if (toolDefinition.setupCommand != null) {
        envWithInput['DART_SETUP_COMMAND'] = toolDefinition.setupCommand[0];
      }
    }
    var substitutions = envWithInput.map<RegExp, String>((key, value) {
      String escapedKey = RegExp.escape(key);
      return MapEntry(RegExp('\\\$(\\($escapedKey\\)|$escapedKey\\b)'), value);
    });
    var argsWithInput = <String>[];
    for (var arg in args) {
      var newArg = arg;
      substitutions
          .forEach((regex, value) => newArg = newArg.replaceAll(regex, value));
      argsWithInput.add(newArg);
    }

    if (toolDefinition.setupCommand != null && !toolDefinition.setupComplete)
      await _runSetup(tool, toolDefinition, envWithInput, toolErrorCallback);

    argsWithInput = toolArgs + argsWithInput;
    var commandPath;
    void Function() callCompleter;
    if (toolDefinition is DartToolDefinition) {
      var modified = await toolDefinition
          .modifyArgsToCreateSnapshotIfNeeded(argsWithInput);
      commandPath = modified.item1;
      callCompleter = modified.item2;
    } else {
      commandPath = argsWithInput.removeAt(0);
    }

    if (callCompleter != null) {
      return _runProcess(tool, content, commandPath, argsWithInput,
              envWithInput, toolErrorCallback)
          .whenComplete(callCompleter);
    } else {
      return _runProcess(tool, content, commandPath, argsWithInput,
          envWithInput, toolErrorCallback);
    }
  }
}
