// 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) {
    if (_shouldCollect != null) {
      return _shouldCollect(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) {
      if (_shouldCollect != null && _shouldCollect(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);
  }
}
