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

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    show ElementKind, Location;
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/generator.dart';

/// The information about a requested set of navigation information when
/// computing navigation information in a `.dart` file.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartNavigationRequest implements NavigationRequest {
  /// The analysis result for the file in which the navigation regions are being
  /// requested.
  ResolvedUnitResult get result;
}

/// An object that [NavigationContributor]s use to record navigation regions.
///
/// Clients may not extend, implement or mix-in this class.
abstract class NavigationCollector {
  /// Whether the collector is collecting target code locations. Computers can
  /// skip computing these if this is false.
  bool get collectCodeLocations;

  /// Record a new navigation region corresponding to the given [range] that
  /// should navigate to the given [targetNameLocation].
  void addRange(
      SourceRange range, ElementKind targetKind, Location targetLocation,
      {Location targetCodeLocation});

  /// Record a new navigation region with the given [offset] and [length] that
  /// should navigate to the given [targetNameLocation].
  void addRegion(int offset, int length, ElementKind targetKind,
      Location targetNameLocation,
      {Location? targetCodeLocation});
}

/// An object used to produce navigation regions.
///
/// Clients may implement this class when implementing plugins.
abstract class NavigationContributor {
  /// Contribute navigation regions for the portion of the file specified by the
  /// given [request] into the given [collector].
  void computeNavigation(
      NavigationRequest request, NavigationCollector collector);
}

/// A generator that will generate an 'analysis.navigation' notification.
///
/// Clients may not extend, implement or mix-in this class.
class NavigationGenerator {
  /// The contributors to be used to generate the navigation data.
  final List<NavigationContributor> contributors;

  /// Initialize a newly created navigation generator to use the given
  /// [contributors].
  NavigationGenerator(this.contributors);

  /// Create an 'analysis.navigation' notification for the portion of the file
  /// specified by the given [request]. If any of the contributors throws an
  /// exception, also create a non-fatal 'plugin.error' notification.
  GeneratorResult generateNavigationNotification(NavigationRequest request) {
    var notifications = <Notification>[];
    var collector = NavigationCollectorImpl();
    for (var contributor in contributors) {
      try {
        contributor.computeNavigation(request, collector);
      } catch (exception, stackTrace) {
        notifications.add(PluginErrorParams(
                false, exception.toString(), stackTrace.toString())
            .toNotification());
      }
    }
    collector.createRegions();
    notifications.add(AnalysisNavigationParams(
            request.path, collector.regions, collector.targets, collector.files)
        .toNotification());
    return GeneratorResult(null, notifications);
  }

  /// Create an 'analysis.getNavigation' response for the portion of the file
  /// specified by the given [request]. If any of the contributors throws an
  /// exception, also create a non-fatal 'plugin.error' notification.
  GeneratorResult<AnalysisGetNavigationResult> generateNavigationResponse(
      NavigationRequest request) {
    var notifications = <Notification>[];
    var collector = NavigationCollectorImpl();
    for (var contributor in contributors) {
      try {
        contributor.computeNavigation(request, collector);
      } catch (exception, stackTrace) {
        notifications.add(PluginErrorParams(
                false, exception.toString(), stackTrace.toString())
            .toNotification());
      }
    }
    collector.createRegions();
    var result = AnalysisGetNavigationResult(
        collector.files, collector.targets, collector.regions);
    return GeneratorResult(result, notifications);
  }
}

/// The information about a requested set of navigation information.
///
/// Clients may not extend, implement or mix-in this class.
abstract class NavigationRequest {
  /// Return the length of the region within the source for which navigation
  /// regions are being requested.
  int? get length;

  /// Return the offset of the region within the source for which navigation
  /// regions are being requested.
  int get offset;

  /// Return the path of the file in which navigation regions are being
  /// requested.
  String get path;

  /// Return the resource provider associated with this request.
  ResourceProvider get resourceProvider;
}
