// Copyright (c) 2014, 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:async';
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

import 'command_runner.dart';
import 'entrypoint.dart';
import 'exceptions.dart';
import 'executable.dart' as exec;
import 'io.dart';
import 'lock_file.dart';
import 'log.dart' as log;
import 'package.dart';
import 'package_name.dart';
import 'pub_embeddable_command.dart';
import 'pubspec.dart';
import 'sdk.dart';
import 'sdk/dart.dart';
import 'solver.dart';
import 'solver/incompatibility_cause.dart';
import 'solver/report.dart';
import 'source/cached.dart';
import 'source/git.dart';
import 'source/hosted.dart';
import 'source/path.dart';
import 'system_cache.dart';
import 'utils.dart';

/// Maintains the set of packages that have been globally activated.
///
/// These have been hand-chosen by the user to make their executables in bin/
/// available to the entire system. This lets them access them even when the
/// current working directory is not inside another entrypoint package.
///
/// Only one version of a given package name can be globally activated at a
/// time. Activating a different version of a package will deactivate the
/// previous one.
///
/// This handles packages from uncached and cached sources a little differently.
/// For a cached source, the package is physically in the user's pub cache and
/// we don't want to mess with it by putting a lockfile in there. Instead, when
/// we activate the package, we create a full lockfile and put it in the
/// "global_packages" directory. It's named "<package>.lock". Unlike a normal
/// lockfile, it also contains an entry for the root package itself, so that we
/// know the version and description that was activated.
///
/// Uncached packages (i.e. "path" packages) are somewhere else on the user's
/// local file system and can have a lockfile directly in place. (And, in fact,
/// we want to ensure we honor the user's lockfile there.) To activate it, we
/// just need to know where that package directory is. For that, we create a
/// lockfile that *only* contains the root package's [PackageId] -- basically
/// just the path to the directory where the real lockfile lives.
class GlobalPackages {
  /// The [SystemCache] containing the global packages.
  final SystemCache cache;

  /// The directory where the lockfiles for activated packages are stored.
  String get _directory => p.join(cache.rootDir, 'global_packages');

  String _packageDir(String packageName) => p.join(_directory, packageName);

  /// The directory where binstubs for global package executables are stored.
  String get _binStubDir => p.join(cache.rootDir, 'bin');

  /// Creates a new global package registry backed by the given directory on
  /// the user's file system.
  ///
  /// The directory may not physically exist yet. If not, this will create it
  /// when needed.
  GlobalPackages(this.cache);

  /// Caches the package located in the Git repository [repo] and makes it the
  /// active global version.
  ///
  /// [executables] is the names of the executables that should have binstubs.
  /// If `null`, all executables in the package will get binstubs. If empty, no
  /// binstubs will be created.
  ///
  /// The [features] map controls which features of the package to activate.
  ///
  /// If [overwriteBinStubs] is `true`, any binstubs that collide with
  /// existing binstubs in other packages will be overwritten by this one's.
  /// Otherwise, the previous ones will be preserved.
  Future<void> activateGit(
    String repo,
    List<String>? executables, {
    required bool overwriteBinStubs,
    String? path,
    String? ref,
  }) async {
    var name = await cache.git.getPackageNameFromRepo(
      repo,
      ref,
      path,
      cache,
      relativeTo: p.current,
    );

    // TODO(nweiz): Add some special handling for git repos that contain path
    // dependencies. Their executables shouldn't be cached, and there should
    // be a mechanism for redoing dependency resolution if a path pubspec has
    // changed (see also issue 20499).
    PackageRef packageRef;
    try {
      packageRef = cache.git.parseRef(
        name,
        {
          'url': repo,
          if (path != null) 'path': path,
          if (ref != null) 'ref': ref,
        },
        containingDir: '.',
      );
    } on FormatException catch (e) {
      throw ApplicationException(e.message);
    }
    await _installInCache(
      packageRef.withConstraint(VersionConstraint.any),
      executables,
      overwriteBinStubs: overwriteBinStubs,
    );
  }

  /// Finds the latest version of the hosted package with [name] that matches
  /// [constraint] and makes it the active global version.
  ///
  /// [executables] is the names of the executables that should have binstubs.
  /// If `null`, all executables in the package will get binstubs. If empty, no
  /// binstubs will be created.
  ///
  /// if [overwriteBinStubs] is `true`, any binstubs that collide with
  /// existing binstubs in other packages will be overwritten by this one's.
  /// Otherwise, the previous ones will be preserved.
  ///
  /// [url] is an optional custom pub server URL. If not null, the package to be
  /// activated will be fetched from this URL instead of the default pub URL.
  Future<void> activateHosted(
    PackageRange range,
    List<String>? executables, {
    required bool overwriteBinStubs,
    String? url,
  }) async {
    await _installInCache(
      range,
      executables,
      overwriteBinStubs: overwriteBinStubs,
    );
  }

  /// Makes the local package at [path] globally active.
  ///
  /// [executables] is the names of the executables that should have binstubs.
  /// If `null`, all executables in the package will get binstubs. If empty, no
  /// binstubs will be created.
  ///
  /// if [overwriteBinStubs] is `true`, any binstubs that collide with
  /// existing binstubs in other packages will be overwritten by this one's.
  /// Otherwise, the previous ones will be preserved.
  Future<void> activatePath(
    String path,
    List<String>? executables, {
    required bool overwriteBinStubs,
    required PubAnalytics? analytics,
  }) async {
    var entrypoint = Entrypoint(path, cache);

    // Get the package's dependencies.
    await entrypoint.acquireDependencies(
      SolveType.get,
      analytics: analytics,
    );
    var name = entrypoint.root.name;
    _describeActive(name, cache);

    // Write a lockfile that points to the local package.
    var fullPath = canonicalize(entrypoint.rootDir);
    var id = cache.path.idFor(
      name,
      entrypoint.root.version,
      fullPath,
      p.current,
    );

    final tempDir = cache.createTempDir();
    // TODO(rnystrom): Look in "bin" and display list of binaries that
    // user can run.
    LockFile([id]).writeToFile(p.join(tempDir, 'pubspec.lock'), cache);

    tryDeleteEntry(_packageDir(name));
    tryRenameDir(tempDir, _packageDir(name));

    _updateBinStubs(
      entrypoint,
      entrypoint.root,
      executables,
      overwriteBinStubs: overwriteBinStubs,
    );
    log.message('Activated ${_formatPackage(id)}.');
  }

  /// Installs the package [dep] and its dependencies into the system cache.
  ///
  /// If [silent] less logging will be printed.
  Future<void> _installInCache(
    PackageRange dep,
    List<String>? executables, {
    required bool overwriteBinStubs,
    bool silent = false,
  }) async {
    final name = dep.name;
    LockFile? originalLockFile = _describeActive(name, cache);

    // Create a dummy package with just [dep] so we can do resolution on it.
    var root = Package.inMemory(
      Pubspec(
        'pub global activate',
        dependencies: [dep],
        sources: cache.sources,
      ),
    );

    // Resolve it and download its dependencies.
    SolveResult result;
    try {
      result = await log.spinner(
        'Resolving dependencies',
        () => resolveVersions(SolveType.get, cache, root),
        condition: !silent,
      );
    } on SolveFailure catch (error) {
      for (var incompatibility
          in error.incompatibility.externalIncompatibilities) {
        if (incompatibility.cause != IncompatibilityCause.noVersions) continue;
        if (incompatibility.terms.single.package.name != name) continue;
        // If the SolveFailure is caused by [dep] not
        // being available, report that as a [dataError].
        dataError(error.toString());
      }
      rethrow;
    }
    // We want the entrypoint to be rooted at 'dep' not the dummy-package.
    result.packages.removeWhere((id) => id.name == 'pub global activate');

    final lockFile = await result.downloadCachedPackages(cache);
    final sameVersions =
        originalLockFile != null && originalLockFile.samePackageIds(lockFile);

    final PackageId id = lockFile.packages[name]!;
    if (sameVersions) {
      log.message('''
The package $name is already activated at newest available version.
To recompile executables, first run `$topLevelProgram pub global deactivate $name`.
''');
    } else {
      // Only precompile binaries if we have a new resolution.
      if (!silent) {
        await SolveReport(
          SolveType.get,
          null,
          root.pubspec,
          originalLockFile ?? LockFile.empty(),
          lockFile,
          result.availableVersions,
          cache,
          dryRun: false,
          quiet: false,
          enforceLockfile: false,
        ).show();
      }

      final tempDir = cache.createTempDir();
      lockFile.writeToFile(p.join(tempDir, 'pubspec.lock'), cache);

      // Load the package graph from [result] so we don't need to re-parse all
      // the pubspecs.
      final entrypoint = Entrypoint.global(
        tempDir,
        cache.loadCached(id),
        lockFile,
        cache,
        solveResult: result,
      );

      await entrypoint.writePackageConfigFile();

      await entrypoint.precompileExecutables();

      tryDeleteEntry(_packageDir(name));
      tryRenameDir(tempDir, _packageDir(name));
    }

    final entrypoint = Entrypoint.global(
      _packageDir(id.name),
      cache.loadCached(id),
      lockFile,
      cache,
      solveResult: result,
    );
    _updateBinStubs(
      entrypoint,
      cache.load(entrypoint.lockFile.packages[dep.name]!),
      executables,
      overwriteBinStubs: overwriteBinStubs,
    );
    if (!silent) log.message('Activated ${_formatPackage(id)}.');
  }

  /// Shows the user the currently active package with [name], if any.
  LockFile? _describeActive(String name, SystemCache cache) {
    late final LockFile lockFile;
    try {
      lockFile = LockFile.load(_getLockFilePath(name), cache.sources);
    } on IOException {
      // Couldn't read the lock file. It probably doesn't exist.
      return null;
    }
    var id = lockFile.packages[name]!;
    final description = id.description.description;

    if (description is GitDescription) {
      log.message('Package ${log.bold(name)} is currently active from Git '
          'repository "${GitDescription.prettyUri(description.url)}".');
    } else if (description is PathDescription) {
      log.message('Package ${log.bold(name)} is currently active at path '
          '"${description.path}".');
    } else {
      log.message('Package ${log.bold(name)} is currently active at version '
          '${log.bold(id.version)}.');
    }
    return lockFile;
  }

  /// Deactivates a previously-activated package named [name].
  ///
  /// Returns `false` if no package with [name] was currently active.
  bool deactivate(String name) {
    var dir = p.join(_directory, name);
    if (!dirExists(_directory)) {
      return false;
    }
    // By listing all files instead of using only `dirExists` this check will
    // work on case-preserving file-systems.
    final files = listDir(_directory);
    if (!files.contains(dir)) {
      return false;
    }
    if (!dirExists(dir)) {
      // This can happen if `dir` was really a file.
      return false;
    }

    _deleteBinStubs(name);

    var lockFile = LockFile.load(_getLockFilePath(name), cache.sources);
    var id = lockFile.packages[name]!;
    log.message('Deactivated package ${_formatPackage(id)}.');

    deleteEntry(dir);

    return true;
  }

  /// Finds the active package with [name].
  ///
  /// Returns an [Entrypoint] loaded with the active package if found.
  Future<Entrypoint> find(String name) async {
    var lockFilePath = _getLockFilePath(name);
    late LockFile lockFile;
    try {
      lockFile = LockFile.load(lockFilePath, cache.sources);
    } on IOException {
      // If we couldn't read the lock file, it's not activated.
      dataError('No active package ${log.bold(name)}.');
    }

    // Remove the package itself from the lockfile. We put it in there so we
    // could find and load the [Package] object, but normally an entrypoint
    // doesn't expect to be in its own lockfile.
    var id = lockFile.packages[name]!;
    lockFile = lockFile.removePackage(name);

    Entrypoint entrypoint;
    if (id.source is CachedSource) {
      // For cached sources, the package itself is in the cache and the
      // lockfile is the one we just loaded.
      entrypoint = Entrypoint.global(
        _packageDir(id.name),
        cache.loadCached(id),
        lockFile,
        cache,
      );
    } else {
      // For uncached sources (i.e. path), the ID just points to the real
      // directory for the package.
      entrypoint = Entrypoint(
        (id.description.description as PathDescription).path,
        cache,
      );
    }

    entrypoint.root.pubspec.sdkConstraints.forEach((sdkName, constraint) {
      var sdk = sdks[sdkName];
      if (sdk == null) {
        dataError('${log.bold(name)} ${entrypoint.root.version} requires '
            'unknown SDK "$name".');
      } else if (sdkName == 'dart') {
        if (constraint.effectiveConstraint.allows((sdk as DartSdk).version)) {
          return;
        }
        dataError("${log.bold(name)} ${entrypoint.root.version} doesn't "
            'support Dart ${sdk.version}.');
      } else {
        dataError('${log.bold(name)} ${entrypoint.root.version} requires the '
            '${sdk.name} SDK, which is unsupported for global executables.');
      }
    });

    // Check that the SDK constraints the lockFile says we have are honored.
    lockFile.sdkConstraints.forEach((sdkName, constraint) {
      var sdk = sdks[sdkName];
      if (sdk == null) {
        dataError('${log.bold(name)} as globally activated requires '
            'unknown SDK "$name".');
      } else if (sdkName == 'dart') {
        if (constraint.effectiveConstraint.allows((sdk as DartSdk).version)) {
          return;
        }
        dataError('''
${log.bold(name)} as globally activated doesn't support Dart ${sdk.version}.

try:
`$topLevelProgram pub global activate $name` to reactivate.
''');
      } else {
        dataError('${log.bold(name)} as globally activated requires the '
            '${sdk.name} SDK, which is unsupported for global executables.');
      }
    });

    return entrypoint;
  }

  /// Runs [package]'s [executable] with [args].
  ///
  /// If [executable] is available in its built form, that will be
  /// recompiled if the SDK has been upgraded since it was first compiled and
  /// then run. Otherwise, it will be run from source.
  ///
  /// If [enableAsserts] is true, the program is run with assertions enabled.
  ///
  /// Returns the exit code from the executable.
  Future<int> runExecutable(
    Entrypoint entrypoint,
    exec.Executable executable,
    List<String> args, {
    bool enableAsserts = false,
    required Future<void> Function(exec.Executable) recompile,
    List<String> vmArgs = const [],
    required bool alwaysUseSubprocess,
  }) async {
    return await exec.runExecutable(
      entrypoint,
      executable,
      args,
      enableAsserts: enableAsserts,
      recompile: (exectuable) async {
        await recompile(exectuable);
        _refreshBinStubs(entrypoint, executable);
      },
      vmArgs: vmArgs,
      alwaysUseSubprocess: alwaysUseSubprocess,
    );
  }

  /// Gets the path to the lock file for an activated cached package with
  /// [name].
  String _getLockFilePath(String name) =>
      p.join(_directory, name, 'pubspec.lock');

  /// Shows the user a formatted list of globally activated packages.
  void listActivePackages() {
    if (!dirExists(_directory)) return;

    listDir(_directory).map(_loadPackageId).toList()
      ..sort((id1, id2) => id1.name.compareTo(id2.name))
      ..forEach((id) => log.message(_formatPackage(id)));
  }

  /// Returns the [PackageId] for the globally-activated package at [path].
  ///
  /// [path] should be a path within [_directory]. It can either be an old-style
  /// path to a single lockfile or a new-style path to a directory containing a
  /// lockfile.
  PackageId _loadPackageId(String path) {
    var name = p.basenameWithoutExtension(path);
    if (!fileExists(path)) path = p.join(path, 'pubspec.lock');

    var id =
        LockFile.load(p.join(_directory, path), cache.sources).packages[name];

    if (id == null) {
      throw FormatException("Pubspec for activated package $name didn't "
          'contain an entry for itself.');
    }

    return id;
  }

  /// Returns formatted string representing the package [id].
  String _formatPackage(PackageId id) {
    final description = id.description.description;
    if (description is GitDescription) {
      var url = GitDescription.prettyUri(description.url);
      return '${log.bold(id.name)} ${id.version} from Git repository "$url"';
    } else if (description is PathDescription) {
      var path = description.path;
      return '${log.bold(id.name)} ${id.version} at path "$path"';
    } else {
      return '${log.bold(id.name)} ${id.version}';
    }
  }

  /// Repairs any corrupted globally-activated packages and their binstubs.
  ///
  /// Returns a pair of two lists of strings. The first indicates which packages
  /// were successfully re-activated; the second indicates which failed.
  Future<Pair<List<String>, List<String>>> repairActivatedPackages() async {
    var executables = <String, List<String>>{};
    if (dirExists(_binStubDir)) {
      for (var entry in listDir(_binStubDir)) {
        try {
          var binstub = readTextFile(entry);
          var package = _binStubProperty(binstub, 'Package');
          if (package == null) {
            throw ApplicationException("No 'Package' property.");
          }

          var executable = _binStubProperty(binstub, 'Executable');
          if (executable == null) {
            throw ApplicationException("No 'Executable' property.");
          }

          executables.putIfAbsent(package, () => []).add(executable);
        } catch (error, stackTrace) {
          log.error(
            'Error reading binstub for '
            '"${p.basenameWithoutExtension(entry)}"',
            error,
            stackTrace,
          );

          tryDeleteEntry(entry);
        }
      }
    }

    var successes = <String>[];
    var failures = <String>[];
    if (dirExists(_directory)) {
      for (var entry in listDir(_directory)) {
        PackageId? id;
        try {
          id = _loadPackageId(entry);
          log.message('Reactivating ${log.bold(id.name)} ${id.version}...');

          var entrypoint = await find(id.name);
          final packageExecutables = executables.remove(id.name) ?? [];

          if (entrypoint.isCached) {
            deleteEntry(entrypoint.globalDir!);
            await _installInCache(
              id.toRange(),
              packageExecutables,
              overwriteBinStubs: true,
              silent: true,
            );
          } else {
            await activatePath(
              entrypoint.rootDir,
              packageExecutables,
              overwriteBinStubs: true,
              analytics: null,
            );
          }
          successes.add(id.name);
        } catch (error, stackTrace) {
          var message = 'Failed to reactivate '
              '${log.bold(p.basenameWithoutExtension(entry))}';
          if (id != null) {
            message += ' ${id.version}';
            if (id.source is! HostedSource) message += ' from ${id.source}';
          }

          log.error(message, error, stackTrace);
          failures.add(p.basenameWithoutExtension(entry));

          tryDeleteEntry(entry);
        }
      }
    }

    if (executables.isNotEmpty) {
      var message = StringBuffer('Binstubs exist for non-activated '
          'packages:\n');
      executables.forEach((package, executableNames) {
        for (var executable in executableNames) {
          deleteEntry(p.join(_binStubDir, executable));
        }

        message.writeln('  From ${log.bold(package)}: '
            '${toSentence(executableNames)}');
      });
      log.error(message);
    }

    return Pair(successes, failures);
  }

  /// Rewrites all binstubs that refer to [executable] of [entrypoint].
  ///
  /// This is meant to be called after a recompile due to eg. outdated
  /// snapshots.
  void _refreshBinStubs(Entrypoint entrypoint, exec.Executable executable) {
    if (!dirExists(_binStubDir)) return;
    for (var file in listDir(_binStubDir, includeDirs: false)) {
      var contents = readTextFile(file);
      var binStubPackage = _binStubProperty(contents, 'Package');
      var binStubScript = _binStubProperty(contents, 'Script');
      if (binStubPackage == null || binStubScript == null) {
        log.fine('Could not parse binstub $file:\n$contents');
        continue;
      }
      if (binStubPackage == entrypoint.root.name &&
          binStubScript ==
              p.basenameWithoutExtension(executable.relativePath)) {
        log.fine('Replacing old binstub $file');
        deleteEntry(file);
        _createBinStub(
          entrypoint.root,
          p.basenameWithoutExtension(file),
          binStubScript,
          overwrite: true,
          snapshot: entrypoint.pathOfExecutable(executable),
        );
      }
    }
  }

  /// Updates the binstubs for [package].
  ///
  /// A binstub is a little shell script in `PUB_CACHE/bin` that runs an
  /// executable from a globally activated package. This removes any old
  /// binstubs from the previously activated version of the package and
  /// (optionally) creates new ones for the executables listed in the package's
  /// pubspec.
  ///
  /// [executables] is the names of the executables that should have binstubs.
  /// If `null`, all executables in the package will get binstubs. If empty, no
  /// binstubs will be created.
  ///
  /// If [overwriteBinStubs] is `true`, any binstubs that collide with
  /// existing binstubs in other packages will be overwritten by this one's.
  /// Otherwise, the previous ones will be preserved.
  ///
  /// If [suggestIfNotOnPath] is `true` (the default), this will warn the user if
  /// the bin directory isn't on their path.
  void _updateBinStubs(
    Entrypoint entrypoint,
    Package package,
    List<String>? executables, {
    required bool overwriteBinStubs,
    bool suggestIfNotOnPath = true,
  }) {
    // Remove any previously activated binstubs for this package, in case the
    // list of executables has changed.
    _deleteBinStubs(package.name);

    if ((executables != null && executables.isEmpty) ||
        package.pubspec.executables.isEmpty) {
      return;
    }

    ensureDir(_binStubDir);

    var installed = <String>[];
    var collided = <String, String>{};
    var allExecutables = ordered(package.pubspec.executables.keys);
    for (var executable in allExecutables) {
      if (executables != null && !executables.contains(executable)) continue;

      var script = package.pubspec.executables[executable]!;

      var previousPackage = _createBinStub(
        package,
        executable,
        script,
        overwrite: overwriteBinStubs,
        snapshot: entrypoint.pathOfExecutable(
          exec.Executable.adaptProgramName(package.name, script),
        ),
      );
      if (previousPackage != null) {
        collided[executable] = previousPackage;

        if (!overwriteBinStubs) continue;
      }

      installed.add(executable);
    }

    if (installed.isNotEmpty) {
      var names = namedSequence('executable', installed.map(log.bold));
      log.message('Installed $names.');
    }

    // Show errors for any collisions.
    if (collided.isNotEmpty) {
      for (var command in ordered(collided.keys)) {
        if (overwriteBinStubs) {
          log.warning('Replaced ${log.bold(command)} previously installed from '
              '${log.bold(collided[command])}.');
        } else {
          log.warning('Executable ${log.bold(command)} was already installed '
              'from ${log.bold(collided[command])}.');
        }
      }

      if (!overwriteBinStubs) {
        log.warning('Deactivate the other package(s) or activate '
            '${log.bold(package.name)} using --overwrite.');
      }
    }

    // Show errors for any unknown executables.
    if (executables != null) {
      var unknown = ordered(
        executables
            .where((exe) => !package.pubspec.executables.keys.contains(exe)),
      );
      if (unknown.isNotEmpty) {
        dataError("Unknown ${namedSequence('executable', unknown)}.");
      }
    }

    // Show errors for any missing scripts.
    // TODO(rnystrom): This can print false positives since a script may be
    // produced by a transformer. Do something better.
    var binFiles = package.executablePaths;
    for (var executable in installed) {
      var script = package.pubspec.executables[executable];
      var scriptPath = p.join('bin', '$script.dart');
      if (!binFiles.contains(scriptPath)) {
        log.warning('Warning: Executable "$executable" runs "$scriptPath", '
            'which was not found in ${log.bold(package.name)}.');
      }
    }

    if (suggestIfNotOnPath && installed.isNotEmpty) {
      _suggestIfNotOnPath(installed.first);
    }
  }

  /// Creates a binstub named [executable] that runs [script] from [package].
  ///
  /// If [overwrite] is `true`, this will replace an existing binstub with that
  /// name for another package.
  ///
  /// [snapshot] is a path to a snapshot file. If that snapshot exists the
  /// binstub will invoke that directly. Otherwise, it will run
  /// `pub global run`.
  ///
  /// If a collision occurs, returns the name of the package that owns the
  /// existing binstub. Otherwise returns `null`.
  String? _createBinStub(
    Package package,
    String executable,
    String script, {
    required bool overwrite,
    required String snapshot,
  }) {
    var binStubPath = p.join(_binStubDir, executable);
    if (Platform.isWindows) binStubPath += '.bat';

    // See if the binstub already exists. If so, it's for another package
    // since we already deleted all of this package's binstubs.
    String? previousPackage;
    if (fileExists(binStubPath)) {
      var contents = readTextFile(binStubPath);
      previousPackage = _binStubProperty(contents, 'Package');
      if (previousPackage == null) {
        log.fine('Could not parse binstub $binStubPath:\n$contents');
      } else if (!overwrite) {
        return previousPackage;
      }
    }

    late String binstub;
    // Batch files behave in funky ways if they are modified while updating.
    // To ensure that the byte-offsets of everything stays the same even if the
    // snapshot filename changes we insert some padding in lines containing the
    // snapshot.
    // 260 is the maximal short path length on Windows. Hopefully that is
    // enough.
    final padding = ' ' * (260 - snapshot.length);
    // We need an absolute path since relative ones won't be relative to the
    // right directory when the user runs this.
    snapshot = p.absolute(snapshot);
    if (Platform.isWindows) {
      binstub = '''
@echo off
rem This file was created by pub v${sdk.version}.
rem Package: ${package.name}
rem Version: ${package.version}
rem Executable: $executable
rem Script: $script
if exist "$snapshot" $padding(
  call dart "$snapshot" $padding%*
  rem The VM exits with code 253 if the snapshot version is out-of-date.
  rem If it is, we need to delete it and run "pub global" manually.
  if not errorlevel 253 (
    goto error
  )
  call dart pub global run ${package.name}:$script %*
) else (
  call dart pub global run ${package.name}:$script %*
)
goto eof
:error
exit /b %errorlevel%
:eof
''';
    } else {
      binstub = '''
#!/usr/bin/env sh
# This file was created by pub v${sdk.version}.
# Package: ${package.name}
# Version: ${package.version}
# Executable: $executable
# Script: $script
if [ -f $snapshot ]; then
  dart "$snapshot" "\$@"
  # The VM exits with code 253 if the snapshot version is out-of-date.
  # If it is, we need to delete it and run "pub global" manually.
  exit_code=\$?
  if [ \$exit_code != 253 ]; then
    exit \$exit_code
  fi
  dart pub global run ${package.name}:$script "\$@"
else
  dart pub global run ${package.name}:$script "\$@"
fi
''';
    }

    // Write the binstub to a temporary location, make it executable and move
    // it into place afterwards to avoid races.
    final tempDir = cache.createTempDir();
    try {
      final tmpPath = p.join(tempDir, binStubPath);

      // Write this as the system encoding since the system is going to
      // execute it and it might contain non-ASCII characters in the
      // pathnames.
      writeTextFile(tmpPath, binstub, encoding: const SystemEncoding());

      if (Platform.isLinux || Platform.isMacOS) {
        // Make it executable.
        var result = Process.runSync('chmod', ['+x', tmpPath]);
        if (result.exitCode != 0) {
          // Couldn't make it executable so don't leave it laying around.
          fail('Could not make "$tmpPath" executable (exit code '
              '${result.exitCode}):\n${result.stderr}');
        }
      }
      File(tmpPath).renameSync(binStubPath);
    } finally {
      deleteEntry(tempDir);
    }

    return previousPackage;
  }

  /// Deletes all existing binstubs for [package].
  void _deleteBinStubs(String package) {
    if (!dirExists(_binStubDir)) return;

    for (var file in listDir(_binStubDir, includeDirs: false)) {
      var contents = readTextFile(file);
      var binStubPackage = _binStubProperty(contents, 'Package');
      if (binStubPackage == null) {
        log.fine('Could not parse binstub $file:\n$contents');
        continue;
      }

      if (binStubPackage == package) {
        log.fine('Deleting old binstub $file');
        deleteEntry(file);
      }
    }
  }

  /// Checks to see if the binstubs are on the user's PATH and, if not, suggests
  /// that the user add the directory to their PATH.
  ///
  /// [installed] should be the name of an installed executable that can be used
  /// to test whether accessing it on the path works.
  void _suggestIfNotOnPath(String installed) {
    if (Platform.isWindows) {
      // See if the shell can find one of the binstubs.
      // "\q" means return exit code 0 if found or 1 if not.
      var result = runProcessSync('where', [r'\q', '$installed.bat']);
      if (result.exitCode == 0) return;

      log.warning("${log.yellow('Warning:')} Pub installs executables into "
          '${log.bold(_binStubDir)}, which is not on your path.\n'
          "You can fix that by adding that directory to your system's "
          '"Path" environment variable.\n'
          'A web search for "configure windows path" will show you how.');
    } else {
      // See if the shell can find one of the binstubs.
      //
      // The "command" builtin is more reliable than the "which" executable. See
      // http://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then
      var result =
          runProcessSync('command', ['-v', installed], runInShell: true);
      if (result.exitCode == 0) return;

      var binDir = _binStubDir;
      if (binDir.startsWith(Platform.environment['HOME']!)) {
        binDir = p.join(
          r'$HOME',
          p.relative(binDir, from: Platform.environment['HOME']),
        );
      }

      log.warning("${log.yellow('Warning:')} Pub installs executables into "
          '${log.bold(binDir)}, which is not on your path.\n'
          "You can fix that by adding this to your shell's config file "
          '(.bashrc, .bash_profile, etc.):\n'
          '\n'
          "  ${log.bold('export PATH="\$PATH":"$binDir"')}\n"
          '\n');
    }
  }

  /// Returns the value of the property named [name] in the bin stub script
  /// [source].
  String? _binStubProperty(String source, String name) {
    var pattern = RegExp(RegExp.escape(name) + r': ([a-zA-Z0-9_-]+)');
    var match = pattern.firstMatch(source);
    return match == null ? null : match[1];
  }
}
