// 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.

/// A function used to determine whether results should be collected for the
/// file with the given [path].
typedef ShouldCollectPredicate = bool Function(String path);

/// An object used to collect partial results (of type [E]) where the partial
/// results are contributed by plugins.
class ResultCollector<E> {
  /// The id used as a plugin id for contributions from the server.
  final String serverId;

  /// A function used to determine whether results should be collected for the
  /// file whose path is passed in as an argument.
  final ShouldCollectPredicate? _shouldCollect;

  /// A multi-keyed map, where the first key is the (normalized and absolute)
  /// path to the file associated with the results, and the second is the id of
  /// the plugin that provided the partial results. The value is the partial
  /// results contributed by the plugin for the file.
  final Map<String, Map<String, E>> resultMap = <String, Map<String, E>>{};

  /// Initialize a newly created result manager.
  ResultCollector(this.serverId, {ShouldCollectPredicate? predicate})
      : _shouldCollect = predicate;

  /// Clear any results that have been contributed for the file with the given
  /// [filePath], but continue to collect results for the file. This is used
  /// when the results for the specified file are known to be invalid, typically
  /// because the content of the file has been modified.
  void clearResultsForFile(String filePath) {
    resultMap[filePath]?.clear();
  }

  /// Clear any results that have been contributed by the plugin with the given
  /// [pluginId].
  void clearResultsFromPlugin(String pluginId) {
    for (var partialResults in resultMap.values) {
      partialResults.remove(pluginId);
    }
  }

  /// Return an iterator producing the partial results that have been
  /// contributed for the given [filePath].
  List<E> getResults(String filePath) {
    var partialResultMap = resultMap[filePath];
    if (partialResultMap == null) {
      return <E>[];
    }
    var values = partialResultMap.values.toList();
    //
    // Ensure that the server's contributions are always first in the list.
    //
    var serverContributions = partialResultMap[serverId];
    if (serverContributions != null && values.remove(serverContributions)) {
      values.insert(0, serverContributions);
    }
    return values;
  }

  /// Return `true` if this collector is collecting results associated with the
  /// given [filePath].
  bool isCollectingFor(String filePath) {
    var predicate = _shouldCollect;
    if (predicate != null) {
      return predicate(filePath);
    }
    return resultMap.containsKey(filePath);
  }

  /// Record the [partialResults] as having been contributed for the given
  /// [filePath] by the plugin with the given [pluginId].
  void putResults(String filePath, String pluginId, E partialResults) {
    var fileResults = resultMap[filePath];
    if (fileResults == null) {
      var predicate = _shouldCollect;
      if (predicate != null && predicate(filePath)) {
        resultMap[filePath] = <String, E>{pluginId: partialResults};
      }
    } else {
      fileResults[pluginId] = partialResults;
    }
  }

  /// Start collecting results contributed for the file with the given
  /// [filePath]. Unless the collector is told to collect results for a file,
  /// any results that are contributed for that file are discarded.
  void startCollectingFor(String filePath) {
    resultMap.putIfAbsent(filePath, () => <String, E>{});
  }

  /// Stop collecting results contributed for the file with the given
  /// [filePath]. Until the collector is told to start collecting results for
  /// the file, any results that are contributed for the file are discarded.
  void stopCollectingFor(String filePath) {
    resultMap.remove(filePath);
  }
}
