// 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 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:path/path.dart' show Context;
import 'package:platform/platform.dart';

const Map<String, String> _osToPathStyle = const <String, String>{
  'linux': 'posix',
  'macos': 'posix',
  'android': 'posix',
  'ios': 'posix',
  'fuchsia': 'posix',
  'windows': 'windows',
};

/// Sanatizes the executable path on Windows.
/// https://github.com/dart-lang/sdk/issues/37751
String sanitizeExecutablePath(String executable,
    {Platform platform = const LocalPlatform()}) {
  if (executable.isEmpty) {
    return executable;
  }
  if (!platform.isWindows) {
    return executable;
  }
  if (executable.contains(' ') && !executable.contains('"')) {
    // Use quoted strings to indicate where the file name ends and the arguments begin;
    // otherwise, the file name is ambiguous.
    return '"$executable"';
  }
  return executable;
}

/// Searches the `PATH` for the executable that [command] is supposed to launch.
///
/// This first builds a list of candidate paths where the executable may reside.
/// If [command] is already an absolute path, then the `PATH` environment
/// variable will not be consulted, and the specified absolute path will be the
/// only candidate that is considered.
///
/// Once the list of candidate paths has been constructed, this will pick the
/// first such path that represents an existent file.
///
/// Return `null` if there were no viable candidates, meaning the executable
/// could not be found.
///
/// If [platform] is not specified, it will default to the current platform.
String getExecutablePath(
  String command,
  String workingDirectory, {
  Platform platform: const LocalPlatform(),
  FileSystem fs: const LocalFileSystem(),
}) {
  assert(_osToPathStyle[platform.operatingSystem] == fs.path.style.name);

  try {
    workingDirectory ??= fs.currentDirectory.path;
  } on FileSystemException {
    // The `currentDirectory` getter can throw a FileSystemException for example
    // when the process doesn't have read/list permissions in each component of
    // the cwd path. In this case, fall back on '.'.
    workingDirectory ??= '.';
  }
  Context context =
      new Context(style: fs.path.style, current: workingDirectory);

  // TODO(goderbauer): refactor when github.com/google/platform.dart/issues/2
  //     is available.
  String pathSeparator = platform.isWindows ? ';' : ':';

  List<String> extensions = <String>[];
  if (platform.isWindows && context.extension(command).isEmpty) {
    extensions = platform.environment['PATHEXT'].split(pathSeparator);
  }

  List<String> candidates = <String>[];
  if (command.contains(context.separator)) {
    candidates = _getCandidatePaths(
        command, <String>[workingDirectory], extensions, context);
  } else {
    List<String> searchPath = platform.environment['PATH'].split(pathSeparator);
    candidates = _getCandidatePaths(command, searchPath, extensions, context);
  }
  return candidates.firstWhere((String path) => fs.file(path).existsSync(),
      orElse: () => null);
}

/// Returns all possible combinations of `$searchPath\$command.$ext` for
/// `searchPath` in [searchPaths] and `ext` in [extensions].
///
/// If [extensions] is empty, it will just enumerate all
/// `$searchPath\$command`.
/// If [command] is an absolute path, it will just enumerate
/// `$command.$ext`.
Iterable<String> _getCandidatePaths(
  String command,
  List<String> searchPaths,
  List<String> extensions,
  Context context,
) {
  List<String> withExtensions = extensions.isNotEmpty
      ? extensions.map((String ext) => '$command$ext').toList()
      : <String>[command];
  if (context.isAbsolute(command)) {
    return withExtensions;
  }
  return searchPaths
      .map((String path) =>
          withExtensions.map((String command) => context.join(path, command)))
      .expand((Iterable<String> e) => e)
      .toList()
      .cast<String>();
}
