// 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:collection';

import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_parser.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/pub.dart';
import 'package:analyzer/src/manifest/manifest_validator.dart';
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/workspace/bazel.dart';
import 'package:analyzer/src/workspace/bazel_watcher.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
import 'package:path/path.dart' as path;
import 'package:watcher/watcher.dart';
import 'package:yaml/yaml.dart';

/// Enables watching of files generated by Bazel.
///
/// TODO(michalt): This is a temporary flag that we use to disable this
/// functionality due its performance issues. We plan to benchmark and optimize
/// it and re-enable it everywhere.
/// Not private to enable testing.
/// NB: If you set this to `false` remember to disable the
/// `test/integration/serve/bazel_changes_test.dart`.
var experimentalEnableBazelWatching = true;

/// Class that maintains a mapping from included/excluded paths to a set of
/// folders that should correspond to analysis contexts.
abstract class ContextManager {
  /// Get the callback interface used to create, destroy, and update contexts.
  ContextManagerCallbacks get callbacks;

  /// Set the callback interface used to create, destroy, and update contexts.
  set callbacks(ContextManagerCallbacks value);

  /// A table mapping [Folder]s to the [AnalysisDriver]s associated with them.
  Map<Folder, AnalysisDriver> get driverMap;

  /// Return the list of excluded paths (folders and files) most recently passed
  /// to [setRoots].
  List<String> get excludedPaths;

  /// Return the list of included paths (folders and files) most recently passed
  /// to [setRoots].
  List<String> get includedPaths;

  /// Return the existing analysis context that should be used to analyze the
  /// given [path], or `null` if the [path] is not analyzed in any of the
  /// created analysis contexts.
  DriverBasedAnalysisContext? getContextFor(String path);

  /// Return the [AnalysisDriver] for the "innermost" context whose associated
  /// folder is or contains the given path.  ("innermost" refers to the nesting
  /// of contexts, so if there is a context for path /foo and a context for
  /// path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
  /// the context for /foo/bar.)
  ///
  /// If no driver contains the given path, `null` is returned.
  AnalysisDriver? getDriverFor(String path);

  /// Return `true` if the file or directory with the given [path] will be
  /// analyzed in one of the analysis contexts.
  bool isAnalyzed(String path);

  /// Rebuild the set of contexts from scratch based on the data last sent to
  /// [setRoots].
  Future<void> refresh();

  /// Change the set of paths which should be used as starting points to
  /// determine the context directories.
  Future<void> setRoots(List<String> includedPaths, List<String> excludedPaths);
}

/// Callback interface used by [ContextManager] to (a) request that contexts be
/// created, destroyed or updated, (b) inform the client when "pub list"
/// operations are in progress, and (c) determine which files should be
/// analyzed.
///
/// TODO(paulberry): eliminate this interface, and instead have [ContextManager]
/// operations return data structures describing how context state should be
/// modified.
abstract class ContextManagerCallbacks {
  /// Called after analysis contexts are created, usually when new analysis
  /// roots are set, or after detecting a change that required rebuilding
  /// the set of analysis contexts.
  void afterContextsCreated();

  /// Called after analysis contexts are destroyed.
  void afterContextsDestroyed();

  /// An [event] was processed, so analysis state might be different now.
  void afterWatchEvent(WatchEvent event);

  /// The given [file] was removed.
  void applyFileRemoved(String file);

  /// Sent the given watch [event] to any interested plugins.
  void broadcastWatchEvent(WatchEvent event);

  /// Add listeners to the [driver]. This must be the only listener.
  ///
  /// TODO(scheglov) Just pass results in here?
  void listenAnalysisDriver(AnalysisDriver driver);

  /// The `pubspec.yaml` at [path] was added/modified.
  void pubspecChanged(String path);

  /// The `pubspec.yaml` at [path] was removed.
  void pubspecRemoved(String path);

  /// Record error information for the file with the given [path].
  void recordAnalysisErrors(String path, List<protocol.AnalysisError> errors);
}

/// Class that maintains a mapping from included/excluded paths to a set of
/// folders that should correspond to analysis contexts.
class ContextManagerImpl implements ContextManager {
  /// The [ResourceProvider] using which paths are converted into [Resource]s.
  final ResourceProvider resourceProvider;

  /// The manager used to access the SDK that should be associated with a
  /// particular context.
  final DartSdkManager sdkManager;

  /// The path to the package config file override.
  /// If `null`, then the default discovery mechanism is used.
  final String? packagesFile;

  /// The storage for cached results.
  final ByteStore _byteStore;

  /// The cache of file contents shared between context of the collection.
  final FileContentCache _fileContentCache;

  /// The logger used to create analysis contexts.
  final PerformanceLog _performanceLog;

  /// The scheduler used to create analysis contexts, and report status.
  final AnalysisDriverScheduler _scheduler;

  /// The current set of analysis contexts, or `null` if the context roots have
  /// not yet been set.
  AnalysisContextCollectionImpl? _collection;

  /// The context used to work with file system paths.
  path.Context pathContext;

  /// The list of excluded paths (folders and files) most recently passed to
  /// [setRoots].
  @override
  List<String> excludedPaths = <String>[];

  /// The list of included paths (folders and files) most recently passed to
  /// [setRoots].
  @override
  List<String> includedPaths = <String>[];

  /// The instrumentation service used to report instrumentation data.
  final InstrumentationService _instrumentationService;

  @override
  ContextManagerCallbacks callbacks = NoopContextManagerCallbacks();

  @override
  final Map<Folder, AnalysisDriver> driverMap =
      HashMap<Folder, AnalysisDriver>();

  /// Subscriptions to watch included resources for changes.
  final List<StreamSubscription<WatchEvent>> watcherSubscriptions = [];

  /// For each folder, stores the subscription to the Bazel workspace so that we
  /// can establish watches for the generated files.
  final bazelSearchSubscriptions =
      <Folder, StreamSubscription<BazelSearchInfo>>{};

  /// The watcher service running in a separate isolate to watch for changes
  /// to files generated by Bazel.
  ///
  /// Might be `null` if watching Bazel files is not enabled.
  BazelFileWatcherService? bazelWatcherService;

  /// The subscription to changes in the files watched by [bazelWatcherService].
  ///
  /// Might be `null` if watching Bazel files is not enabled.
  StreamSubscription<List<WatchEvent>>? bazelWatcherSubscription;

  /// For each [Folder] store which files are being watched. This allows us to
  /// clean up when we destroy a context.
  final bazelWatchedPathsPerFolder = <Folder, _BazelWatchedFiles>{};

  /// Information about the current/last queued context rebuild.
  ///
  /// This is used when a new build is requested to cancel any in-progress
  /// rebuild and wait for it to terminate before starting the next.
  final _CancellingTaskQueue _currentContextRebuild = _CancellingTaskQueue();

  ContextManagerImpl(
      this.resourceProvider,
      this.sdkManager,
      this.packagesFile,
      this._byteStore,
      this._fileContentCache,
      this._performanceLog,
      this._scheduler,
      this._instrumentationService,
      {required bool enableBazelWatcher})
      : pathContext = resourceProvider.pathContext {
    if (enableBazelWatcher) {
      bazelWatcherService = BazelFileWatcherService(_instrumentationService);
      bazelWatcherSubscription = bazelWatcherService!.events
          .listen((events) => _handleBazelWatchEvents(events));
    }
  }

  @override
  DriverBasedAnalysisContext? getContextFor(String path) {
    try {
      return _collection?.contextFor(path);
    } on StateError {
      return null;
    }
  }

  @override
  AnalysisDriver? getDriverFor(String path) {
    return getContextFor(path)?.driver;
  }

  @override
  bool isAnalyzed(String path) {
    var collection = _collection;
    if (collection == null) {
      return false;
    }

    return collection.contexts.any(
      (context) => context.contextRoot.isAnalyzed(path),
    );
  }

  /// Starts (an asynchronous) rebuild of analysis contexts.
  @override
  Future<void> refresh() async {
    await _createAnalysisContexts();
  }

  /// Updates the analysis roots and waits for the contexts to rebuild.
  ///
  /// If the roots have not changed, exits early without performing any work.
  @override
  Future<void> setRoots(
      List<String> includedPaths, List<String> excludedPaths) async {
    if (_rootsAreUnchanged(includedPaths, excludedPaths)) {
      return;
    }

    this.includedPaths = includedPaths;
    this.excludedPaths = excludedPaths;

    await _createAnalysisContexts();
  }

  /// Use the given analysis [driver] to analyze the content of the analysis
  /// options file at the given [path].
  void _analyzeAnalysisOptionsYaml(AnalysisDriver driver, String path) {
    var convertedErrors = const <protocol.AnalysisError>[];
    try {
      var content = _readFile(path);
      var lineInfo = LineInfo.fromContent(content);
      var errors = analyzeAnalysisOptions(
        resourceProvider.getFile(path).createSource(),
        content,
        driver.sourceFactory,
        driver.currentSession.analysisContext.contextRoot.root.path,
      );
      var converter = AnalyzerConverter();
      convertedErrors = converter.convertAnalysisErrors(errors,
          lineInfo: lineInfo, options: driver.analysisOptions);
    } catch (exception) {
      // If the file cannot be analyzed, fall through to clear any previous
      // errors.
    }
    callbacks.recordAnalysisErrors(path, convertedErrors);
  }

  /// Use the given analysis [driver] to analyze the content of the
  /// AndroidManifest file at the given [path].
  void _analyzeAndroidManifestXml(AnalysisDriver driver, String path) {
    var convertedErrors = const <protocol.AnalysisError>[];
    try {
      var content = _readFile(path);
      var validator =
          ManifestValidator(resourceProvider.getFile(path).createSource());
      var lineInfo = LineInfo.fromContent(content);
      var errors = validator.validate(
          content, driver.analysisOptions.chromeOsManifestChecks);
      var converter = AnalyzerConverter();
      convertedErrors = converter.convertAnalysisErrors(errors,
          lineInfo: lineInfo, options: driver.analysisOptions);
    } catch (exception) {
      // If the file cannot be analyzed, fall through to clear any previous
      // errors.
    }
    callbacks.recordAnalysisErrors(path, convertedErrors);
  }

  /// Use the given analysis [driver] to analyze the content of the
  /// data file at the given [path].
  void _analyzeFixDataYaml(AnalysisDriver driver, String path) {
    var convertedErrors = const <protocol.AnalysisError>[];
    try {
      var file = resourceProvider.getFile(path);
      var packageName = file.parent.parent.shortName;
      var content = _readFile(path);
      var errorListener = RecordingErrorListener();
      var errorReporter = ErrorReporter(
        errorListener,
        file.createSource(),
        isNonNullableByDefault: false,
      );
      var parser = TransformSetParser(errorReporter, packageName);
      parser.parse(content);
      var converter = AnalyzerConverter();
      convertedErrors = converter.convertAnalysisErrors(errorListener.errors,
          lineInfo: LineInfo.fromContent(content),
          options: driver.analysisOptions);
    } catch (exception) {
      // If the file cannot be analyzed, fall through to clear any previous
      // errors.
    }
    callbacks.recordAnalysisErrors(path, convertedErrors);
  }

  /// Use the given analysis [driver] to analyze the content of the pubspec file
  /// at the given [path].
  void _analyzePubspecYaml(AnalysisDriver driver, String path) {
    var convertedErrors = const <protocol.AnalysisError>[];
    try {
      var content = _readFile(path);
      var node = loadYamlNode(content);
      if (node is YamlMap) {
        var validator = PubspecValidator(
            resourceProvider, resourceProvider.getFile(path).createSource());
        var lineInfo = LineInfo.fromContent(content);
        var errors = validator.validate(node.nodes);
        var converter = AnalyzerConverter();
        convertedErrors = converter.convertAnalysisErrors(errors,
            lineInfo: lineInfo, options: driver.analysisOptions);

        if (driver.analysisOptions.lint) {
          var visitors = <LintRule, PubspecVisitor>{};
          for (var linter in driver.analysisOptions.lintRules) {
            if (linter is LintRule) {
              var visitor = linter.getPubspecVisitor();
              if (visitor != null) {
                visitors[linter] = visitor;
              }
            }
          }

          if (visitors.isNotEmpty) {
            var sourceUri = resourceProvider.pathContext.toUri(path);
            var pubspecAst = Pubspec.parse(content,
                sourceUrl: sourceUri, resourceProvider: resourceProvider);
            var listener = RecordingErrorListener();
            var reporter = ErrorReporter(listener,
                resourceProvider.getFile(path).createSource(sourceUri),
                isNonNullableByDefault: false);
            for (var entry in visitors.entries) {
              entry.key.reporter = reporter;
              pubspecAst.accept(entry.value);
            }
            if (listener.errors.isNotEmpty) {
              convertedErrors.addAll(converter.convertAnalysisErrors(
                  listener.errors,
                  lineInfo: lineInfo,
                  options: driver.analysisOptions));
            }
          }
        }
      }
    } catch (exception) {
      // If the file cannot be analyzed, fall through to clear any previous
      // errors.
    }
    callbacks.recordAnalysisErrors(path, convertedErrors);
  }

  void _checkForAndroidManifestXmlUpdate(String path) {
    if (file_paths.isAndroidManifestXml(pathContext, path)) {
      var driver = getDriverFor(path);
      if (driver != null) {
        _analyzeAndroidManifestXml(driver, path);
      }
    }
  }

  void _checkForFixDataYamlUpdate(String path) {
    if (file_paths.isFixDataYaml(pathContext, path)) {
      var driver = getDriverFor(path);
      if (driver != null) {
        _analyzeFixDataYaml(driver, path);
      }
    }
  }

  /// Recreates all analysis contexts.
  ///
  /// If an existing rebuild is in progress, it will be cancelled and this
  /// rebuild will occur only once it has exited.
  ///
  /// Returns a [Future] that completes once the requested rebuild completes.
  Future<void> _createAnalysisContexts() async {
    /// A helper that performs a context rebuild while monitoring the included
    /// paths for changes until the contexts file watchers are ready.
    ///
    /// If changes are detected during the rebuild, the rebuild will be
    /// restarted.
    Future<void> performContextRebuildGuarded(
      CancellationToken cancellationToken,
    ) async {
      /// A helper that performs the context rebuild and waits for all watchers
      /// to be fully initialized.
      Future<void> performContextRebuild() async {
        _destroyAnalysisContexts();
        _fileContentCache.invalidateAll();

        var watchers = <ResourceWatcher>[];
        var collection = _collection = AnalysisContextCollectionImpl(
          includedPaths: includedPaths,
          excludedPaths: excludedPaths,
          byteStore: _byteStore,
          drainStreams: false,
          enableIndex: true,
          performanceLog: _performanceLog,
          resourceProvider: resourceProvider,
          scheduler: _scheduler,
          sdkPath: sdkManager.defaultSdkDirectory,
          packagesFile: packagesFile,
          fileContentCache: _fileContentCache,
        );

        for (var analysisContext in collection.contexts) {
          var driver = analysisContext.driver;

          callbacks.listenAnalysisDriver(driver);

          var rootFolder = analysisContext.contextRoot.root;
          driverMap[rootFolder] = driver;

          for (final included in analysisContext.contextRoot.included) {
            final watcher = included.watch();
            watchers.add(watcher);
            watcherSubscriptions.add(
              watcher.changes.listen(
                _handleWatchEvent,
                onError: _handleWatchInterruption,
              ),
            );
          }

          _watchBazelFilesIfNeeded(rootFolder, driver);

          for (var file in analysisContext.contextRoot.analyzedFiles()) {
            if (file_paths.isAndroidManifestXml(pathContext, file)) {
              _analyzeAndroidManifestXml(driver, file);
            } else if (file_paths.isDart(pathContext, file)) {
              driver.addFile(file);
            }
          }

          var optionsFile = analysisContext.contextRoot.optionsFile;

          if (optionsFile != null &&
              analysisContext.contextRoot.isAnalyzed(optionsFile.path)) {
            _analyzeAnalysisOptionsYaml(driver, optionsFile.path);
          }

          var fixDataYamlFile = rootFolder
              .getChildAssumingFolder('lib')
              .getChildAssumingFile(file_paths.fixDataYaml);
          if (fixDataYamlFile.exists) {
            _analyzeFixDataYaml(driver, fixDataYamlFile.path);
          }

          var pubspecFile =
              rootFolder.getChildAssumingFile(file_paths.pubspecYaml);
          if (pubspecFile.exists &&
              analysisContext.contextRoot.isAnalyzed(pubspecFile.path)) {
            _analyzePubspecYaml(driver, pubspecFile.path);
          }
        }

        // Finally, wait for the new contexts watchers to all become ready so we
        // can ensure they will not lose any future events before we continue.
        await Future.wait(watchers.map((watcher) => watcher.ready));
      }

      /// A helper that returns whether a change to the file at [path] should
      /// restart any in-progress rebuild.
      bool shouldRestartBuild(String path) {
        return file_paths.isDart(pathContext, path) ||
            file_paths.isAnalysisOptionsYaml(pathContext, path) ||
            file_paths.isPubspecYaml(pathContext, path) ||
            file_paths.isPackageConfigJson(pathContext, path);
      }

      if (cancellationToken.isCancellationRequested) {
        return;
      }

      // Create temporary watchers before we start the context build so we can
      // tell if any files were modified while waiting for the "real" watchers to
      // become ready and start the process again.
      final temporaryWatchers = includedPaths
          .map((path) => resourceProvider.getResource(path))
          .map((resource) => resource.watch())
          .toList();

      // If any watcher picks up an important change while we're running the
      // rest of this method, we will need to start again.
      var needsBuild = true;
      final temporaryWatcherSubscriptions = temporaryWatchers
          .map((watcher) => watcher.changes.listen((event) {
                if (shouldRestartBuild(event.path)) {
                  needsBuild = true;
                }
              }))
          .toList();

      try {
        // Ensure all watchers are ready before we begin any rebuild.
        await Future.wait(temporaryWatchers.map((watcher) => watcher.ready));

        // Max number of attempts to rebuild if changes.
        var remainingBuilds = 5;
        while (needsBuild && remainingBuilds-- > 0) {
          // Reset the flag, as we'll only need to rebuild if a temporary
          // watcher fires after this point.
          needsBuild = false;

          if (cancellationToken.isCancellationRequested) {
            return;
          }

          // Attempt a context rebuild. This call will wait for all required
          // watchers to be ready before returning.
          await performContextRebuild();
        }
      } finally {
        // Cancel the temporary watcher subscriptions.
        await Future.wait(
          temporaryWatcherSubscriptions.map((sub) => sub.cancel()),
        );
      }

      if (cancellationToken.isCancellationRequested) {
        return;
      }

      callbacks.afterContextsCreated();
    }

    return _currentContextRebuild.queue(performContextRebuildGuarded);
  }

  /// Clean up and destroy the context associated with the given folder.
  void _destroyAnalysisContext(DriverBasedAnalysisContext context) {
    context.driver.dispose();
    var rootFolder = context.contextRoot.root;
    var watched = bazelWatchedPathsPerFolder.remove(rootFolder);
    if (watched != null) {
      for (var path in watched.paths) {
        bazelWatcherService!.stopWatching(watched.workspace, path);
      }
      _stopWatchingBazelBinPaths(watched);
    }
    bazelSearchSubscriptions.remove(rootFolder)?.cancel();
    driverMap.remove(rootFolder);
  }

  void _destroyAnalysisContexts() {
    var collection = _collection;
    if (collection != null) {
      for (final subscription in watcherSubscriptions) {
        subscription.cancel();
      }
      for (var analysisContext in collection.contexts) {
        _destroyAnalysisContext(analysisContext);
      }
      callbacks.afterContextsDestroyed();
    }
  }

  List<String> _getPossibleBazelBinPaths(_BazelWatchedFiles watched) => [
        pathContext.join(watched.workspace, 'bazel-bin'),
        pathContext.join(watched.workspace, 'blaze-bin'),
      ];

  /// Establishes watch(es) for the Bazel generated files provided in
  /// [notification].
  ///
  /// Whenever the files change, we trigger re-analysis. This allows us to react
  /// to creation/modification of files that were generated by Bazel.
  void _handleBazelSearchInfo(
      Folder folder, String workspace, BazelSearchInfo info) {
    final bazelWatcherService = this.bazelWatcherService;
    if (bazelWatcherService == null) {
      return;
    }

    var watched = bazelWatchedPathsPerFolder.putIfAbsent(
        folder, () => _BazelWatchedFiles(workspace));
    var added = watched.paths.add(info.requestedPath);
    if (added) bazelWatcherService.startWatching(workspace, info);
  }

  /// Notifies the drivers that a generated Bazel file has changed.
  void _handleBazelWatchEvents(List<WatchEvent> events) {
    // First check if we have any changes to the bazel-*/blaze-* paths.  If
    // we do, we'll simply recreate all contexts to make sure that we follow the
    // correct paths.
    var bazelSymlinkPaths = bazelWatchedPathsPerFolder.values
        .expand((watched) => _getPossibleBazelBinPaths(watched))
        .toSet();
    if (events.any((event) => bazelSymlinkPaths.contains(event.path))) {
      refresh();
      return;
    }

    // If a file was created or removed, the URI resolution is likely wrong.
    // Do as for `package_config.json` changes - recreate all contexts.
    if (events
        .map((event) => event.type)
        .any((type) => type == ChangeType.ADD || type == ChangeType.REMOVE)) {
      refresh();
      return;
    }

    // If we have only changes to generated files, notify drivers.
    for (var driver in driverMap.values) {
      for (var event in events) {
        driver.changeFile(event.path);
      }
    }
  }

  void _handleWatchEvent(WatchEvent event) {
    callbacks.broadcastWatchEvent(event);
    _handleWatchEventImpl(event);
    callbacks.afterWatchEvent(event);
  }

  void _handleWatchEventImpl(WatchEvent event) {
    // Figure out which context this event applies to.
    // TODO(brianwilkerson) If a file is explicitly included in one context
    // but implicitly referenced in another context, we will only send a
    // changeSet to the context that explicitly includes the file (because
    // that's the only context that's watching the file).
    var path = event.path;
    var type = event.type;

    _instrumentationService.logWatchEvent('<unknown>', path, type.toString());

    final isPubspec = file_paths.isPubspecYaml(pathContext, path);
    if (file_paths.isAnalysisOptionsYaml(pathContext, path) ||
        file_paths.isBazelBuild(pathContext, path) ||
        file_paths.isPackageConfigJson(pathContext, path) ||
        isPubspec ||
        false) {
      _createAnalysisContexts().then((_) {
        if (isPubspec) {
          if (type == ChangeType.REMOVE) {
            callbacks.pubspecRemoved(path);
          } else {
            callbacks.pubspecChanged(path);
          }
        }
      });

      return;
    }

    var collection = _collection;
    if (collection != null && file_paths.isDart(pathContext, path)) {
      for (var analysisContext in collection.contexts) {
        switch (type) {
          case ChangeType.ADD:
            if (analysisContext.contextRoot.isAnalyzed(path)) {
              analysisContext.driver.addFile(path);
            } else {
              analysisContext.driver.changeFile(path);
            }
            break;
          case ChangeType.MODIFY:
            analysisContext.driver.changeFile(path);
            break;
          case ChangeType.REMOVE:
            analysisContext.driver.removeFile(path);
            break;
        }
      }
    }

    switch (type) {
      case ChangeType.ADD:
      case ChangeType.MODIFY:
        _checkForAndroidManifestXmlUpdate(path);
        _checkForFixDataYamlUpdate(path);
        break;
      case ChangeType.REMOVE:
        callbacks.applyFileRemoved(path);
        break;
    }
  }

  /// On windows, the directory watcher may overflow, and we must recover.
  void _handleWatchInterruption(dynamic error, StackTrace stackTrace) {
    // We've handled the error, so we only have to log it.
    _instrumentationService
        .logError('Watcher error; refreshing contexts.\n$error\n$stackTrace');
    // TODO(mfairhurst): Optimize this, or perhaps be less complete.
    refresh();
  }

  /// Read the contents of the file at the given [path], or throw an exception
  /// if the contents cannot be read.
  String _readFile(String path) {
    return resourceProvider.getFile(path).readAsStringSync();
  }

  /// Checks whether the current roots were built using the same paths as
  /// [includedPaths]/[excludedPaths].
  bool _rootsAreUnchanged(
      List<String> includedPaths, List<String> excludedPaths) {
    if (includedPaths.length != this.includedPaths.length ||
        excludedPaths.length != this.excludedPaths.length) {
      return false;
    }
    final existingIncludedSet = this.includedPaths.toSet();
    final existingExcludedSet = this.excludedPaths.toSet();

    return existingIncludedSet.containsAll(includedPaths) &&
        existingExcludedSet.containsAll(excludedPaths);
  }

  /// Starts watching for the `bazel-bin` and `blaze-bin` symlinks.
  ///
  /// This is important since these symlinks might not be present when the
  /// server starts up, in which case `BazelWorkspace` assumes by default the
  /// Bazel ones.  So we want to detect if the symlinks get created to reset
  /// everything and repeat the search for the folders.
  void _startWatchingBazelBinPaths(_BazelWatchedFiles watched) {
    var watcherService = bazelWatcherService;
    if (watcherService == null) return;
    var paths = _getPossibleBazelBinPaths(watched);
    watcherService.startWatching(
        watched.workspace, BazelSearchInfo(paths[0], paths));
  }

  /// Stops watching for the `bazel-bin` and `blaze-bin` symlinks.
  void _stopWatchingBazelBinPaths(_BazelWatchedFiles watched) {
    var watcherService = bazelWatcherService;
    if (watcherService == null) return;
    var paths = _getPossibleBazelBinPaths(watched);
    watcherService.stopWatching(watched.workspace, paths[0]);
  }

  /// Listens to files generated by Bazel that were found or searched for.
  ///
  /// This is handled specially because the files are outside the package
  /// folder, but we still want to watch for changes to them.
  ///
  /// Does nothing if the [driver] is not in a Bazel workspace.
  void _watchBazelFilesIfNeeded(Folder folder, AnalysisDriver analysisDriver) {
    if (!experimentalEnableBazelWatching) return;
    var watcherService = bazelWatcherService;
    if (watcherService == null) return;

    var workspace = analysisDriver.analysisContext?.contextRoot.workspace;
    if (workspace is BazelWorkspace &&
        !bazelSearchSubscriptions.containsKey(folder)) {
      bazelSearchSubscriptions[folder] = workspace.bazelCandidateFiles.listen(
          (notification) =>
              _handleBazelSearchInfo(folder, workspace.root, notification));

      var watched = _BazelWatchedFiles(workspace.root);
      bazelWatchedPathsPerFolder[folder] = watched;
      _startWatchingBazelBinPaths(watched);
    }
  }
}

class NoopContextManagerCallbacks implements ContextManagerCallbacks {
  @override
  void afterContextsCreated() {}

  @override
  void afterContextsDestroyed() {}

  @override
  void afterWatchEvent(WatchEvent event) {}

  @override
  void applyFileRemoved(String file) {}

  @override
  void broadcastWatchEvent(WatchEvent event) {}

  @override
  void listenAnalysisDriver(AnalysisDriver driver) {}

  @override
  void pubspecChanged(String pubspecPath) {}

  @override
  void pubspecRemoved(String pubspecPath) {}

  @override
  void recordAnalysisErrors(String path, List<protocol.AnalysisError> errors) {}
}

class _BazelWatchedFiles {
  final String workspace;
  final paths = <String>{};
  _BazelWatchedFiles(this.workspace);
}

/// Handles a task queue of tasks that cannot run concurrently.
///
/// Queueing a new task will signal for any in-progress task to cancel and
/// wait for it to complete before starting the new task.
class _CancellingTaskQueue {
  /// A cancellation token for current/last queued task.
  ///
  /// This token is replaced atomically with [_complete] and
  /// together they allow cancelling a task and chaining a new task on
  /// to the end.
  CancelableToken? _cancellationToken;

  /// A [Future] that completes when the current/last queued task finishes.
  ///
  /// This future is replaced atomically with [_cancellationToken] and together
  /// they allow cancelling a task and chaining a new task on to the end.
  Future<void> _complete = Future.value();

  /// Requests that [performTask] is called after first cancelling any
  /// in-progress task and waiting for it to complete.
  ///
  /// Returns a future that completes once the new task has completed.
  Future<void> queue(
    Future<void> Function(CancellationToken cancellationToken) performTask,
  ) {
    // Signal for any in-progress task to cancel.
    _cancellationToken?.cancel();

    // Chain the new task onto the end of any existing one, so the new
    // task never starts until the previous (cancelled) one finishes (which
    // may be by aborting early because of the cancellation signal).
    final token = _cancellationToken = CancelableToken();
    _complete = _complete
        .then((_) => performTask(token))
        .then((_) => _clearTokenIfCurrent(token));

    return _complete;
  }

  /// Clears the current cancellation token if it is [token].
  void _clearTokenIfCurrent(CancelableToken token) {
    if (token == _cancellationToken) {
      _cancellationToken = null;
    }
  }
}
