// 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 'dart:async';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/plugin/plugin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/generator.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';

/**
 * A mixin that can be used when creating a subclass of [ServerPlugin] and
 * mixing in [NavigationMixin]. This implements the creation of the navigation
 * request based on the assumption that the driver being created is an
 * [AnalysisDriver].
 *
 * Clients may not extend or implement this class, but are allowed to use it as
 * a mix-in when creating a subclass of [ServerPlugin] that also uses
 * [NavigationMixin] as a mix-in.
 */
abstract class DartNavigationMixin implements NavigationMixin {
  @override
  Future<NavigationRequest> getNavigationRequest(
      AnalysisGetNavigationParams parameters) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    String path = parameters.file;
    ResolveResult result = await getResolveResult(path);
    int offset = parameters.offset;
    int length = parameters.length;
    if (offset < 0 && length < 0) {
      offset = 0;
      length = result.content.length;
    }
    return new DartNavigationRequestImpl(
        resourceProvider, offset, length, result);
  }
}

/**
 * A mixin that can be used when creating a subclass of [ServerPlugin] to
 * provide most of the implementation for handling navigation requests.
 *
 * Clients may not extend or implement this class, but are allowed to use it as
 * a mix-in when creating a subclass of [ServerPlugin].
 */
abstract class NavigationMixin implements ServerPlugin {
  /**
   * Return a list containing the navigation contributors that should be used to
   * create navigation information for the file with the given [path]
   */
  List<NavigationContributor> getNavigationContributors(String path);

  /**
   * Return the navigation request that should be passes to the contributors
   * returned from [getNavigationContributors].
   *
   * Throw a [RequestFailure] if the request could not be created.
   */
  Future<NavigationRequest> getNavigationRequest(
      AnalysisGetNavigationParams parameters);

  @override
  Future<AnalysisGetNavigationResult> handleAnalysisGetNavigation(
      AnalysisGetNavigationParams parameters) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    String path = parameters.file;
    NavigationRequest request = await getNavigationRequest(parameters);
    NavigationGenerator generator =
        new NavigationGenerator(getNavigationContributors(path));
    GeneratorResult<AnalysisGetNavigationResult> result =
        generator.generateNavigationResponse(request);
    result.sendNotifications(channel);
    return result.result;
  }

  /**
   * Send a navigation notification for the file with the given [path] to the
   * server.
   */
  @override
  Future<void> sendNavigationNotification(String path) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    try {
      NavigationRequest request = await getNavigationRequest(
          new AnalysisGetNavigationParams(path, -1, -1));
      NavigationGenerator generator =
          new NavigationGenerator(getNavigationContributors(path));
      GeneratorResult generatorResult =
          generator.generateNavigationNotification(request);
      generatorResult.sendNotifications(channel);
    } on RequestFailure {
      // If we couldn't analyze the file, then don't send a notification.
    }
  }
}
