// Copyright (c) 2022, 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:convert';

import 'package:analysis_server/src/analytics/percentile_calculator.dart';
import 'package:analysis_server/src/plugin/plugin_isolate.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:path/path.dart' as path;

/// Data about the plugins associated with the context roots.
class PluginData {
  /// The number of times that plugin information has been recorded.
  int recordCount = 0;

  /// A table mapping the IDs of running "new" plugin isolates to various
  /// percentile-based analytics for each plugin.
  Map<String, PluginDataPerIsolate> counts = {};

  /// A table mapping the IDs of running legacy plugins to the percentile-based
  /// analytics regarding the number of context roots associated with each of
  /// the plugins.
  Map<String, PercentileCalculator> usageCounts = {};

  String get usageCountData {
    return json.encode({
      'recordCount': recordCount,
      'rootCounts': _encodeUsageCounts(),
    });
  }

  /// Records data about the plugins that are currently running, via info from
  /// [pluginManager].
  Future<void> recordPlugins(PluginManager pluginManager) async {
    recordCount++;
    for (var isolate in pluginManager.legacyPluginIsolates) {
      usageCounts
          .putIfAbsent(isolate.safePluginId, () => PercentileCalculator())
          .addValue(isolate.contextRoots.length);
    }

    // Record a data point for each context root with _no_ configured new
    // plugins.
    for (var contextRootPath in pluginManager.contextRootsWithNoPlugins) {
      // Plugin analytics are keyed to safe plugin IDs, which are derived from
      // the context root path.
      var pluginEntrypointPath = pluginManager.pluginStateFolderPath(
        contextRootPath,
      );
      var safePluginId = pluginEntrypointPath.asSafePluginId;
      counts.putIfAbsent(
        safePluginId,
        () => PluginDataPerIsolate(pluginCount: 0),
      );
    }

    for (var isolate in pluginManager.newPluginIsolates) {
      var details = await isolate.requestDetails();
      if (details == null) continue;

      var pluginDataPerIsolate = counts.putIfAbsent(
        isolate.safePluginId,
        () => PluginDataPerIsolate(pluginCount: details.plugins.length),
      );

      for (var plugin in details.plugins) {
        pluginDataPerIsolate.lintRuleCounts.addValue(plugin.lintRules.length);
        pluginDataPerIsolate.warningRuleCounts.addValue(
          plugin.warningRules.length,
        );
        pluginDataPerIsolate.fixCounts.addValue(plugin.fixes.length);
        pluginDataPerIsolate.assistCounts.addValue(plugin.assists.length);
      }
    }
  }

  /// Returns an encoding of the [usageCounts].
  Map<String, Object> _encodeUsageCounts() => {
    for (var entry in usageCounts.entries) entry.key: entry.value.toJson(),
  };
}

/// Plugin data (for "new" plugins) for a given plugin isolate.
///
/// Only one plugin isolate runs for a given analysis context.
class PluginDataPerIsolate {
  /// The number of running plugins.
  final int pluginCount;

  /// The percentile-based analytics regarding the number of lint rules which
  /// are registered in each plugin.
  PercentileCalculator lintRuleCounts = PercentileCalculator();

  /// The percentile-based analytics regarding the number of warning rules which
  /// are registered in each plugin.
  PercentileCalculator warningRuleCounts = PercentileCalculator();

  /// The percentile-based analytics regarding the number of quick fixes which
  /// are registered in each plugin.
  PercentileCalculator fixCounts = PercentileCalculator();

  /// The percentile-based analytics regarding the number of quick assists which
  /// are registered in each plugin.
  PercentileCalculator assistCounts = PercentileCalculator();

  PluginDataPerIsolate({required this.pluginCount});
}

extension on String {
  String get asSafePluginId {
    var components = path.split(this);
    if (components.contains('.pub-cache')) {
      var index = components.lastIndexOf('analyzer_plugin');
      if (index > 2 &&
          components[index - 1] == 'tools' &&
          components[index - 3] == 'pub.dev') {
        return components[index - 2];
      }
    }
    return 'unknown';
  }
}

extension PluginIsolateExtension on PluginIsolate {
  /// An ID for this plugin that doesn't contain any PII.
  ///
  /// If the plugin is installed in the pub cache and hosted on `pub.dev`, then
  /// the returned name will be the name and version of the containing package
  /// as listed on `pub.dev`. If not, then it might be an internal name so we
  /// default to 'unknown'.
  String get safePluginId => pluginId.asSafePluginId;
}
