// 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.
   */
  ResolveResult 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 {
  /**
   * Record a new navigation region corresponding to the given [range] that
   * should navigate to the given [targetLocation].
   */
  void addRange(
      SourceRange range, ElementKind targetKind, Location targetLocation);

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

/**
 * 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) {
    List<Notification> notifications = <Notification>[];
    NavigationCollectorImpl collector = new NavigationCollectorImpl();
    for (NavigationContributor contributor in contributors) {
      try {
        contributor.computeNavigation(request, collector);
      } catch (exception, stackTrace) {
        notifications.add(new PluginErrorParams(
                false, exception.toString(), stackTrace.toString())
            .toNotification());
      }
    }
    collector.createRegions();
    notifications.add(new AnalysisNavigationParams(
            request.path, collector.regions, collector.targets, collector.files)
        .toNotification());
    return new 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) {
    List<Notification> notifications = <Notification>[];
    NavigationCollectorImpl collector = new NavigationCollectorImpl();
    for (NavigationContributor contributor in contributors) {
      try {
        contributor.computeNavigation(request, collector);
      } catch (exception, stackTrace) {
        notifications.add(new PluginErrorParams(
                false, exception.toString(), stackTrace.toString())
            .toNotification());
      }
    }
    collector.createRegions();
    AnalysisGetNavigationResult result = new AnalysisGetNavigationResult(
        collector.files, collector.targets, collector.regions);
    return new 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;
}
