// 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/error/error.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/source.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/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/generator.dart';

/**
 * A mixin that can be used when creating a subclass of [ServerPlugin] and
 * mixing in [FixesMixin]. This implements the creation of the fixes 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
 * [FixesMixin] as a mix-in.
 */
abstract class DartFixesMixin implements FixesMixin {
  @override
  Future<FixesRequest> getFixesRequest(EditGetFixesParams parameters) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    String path = parameters.file;
    int offset = parameters.offset;
    ResolveResult result = await getResolveResult(path);
    return new DartFixesRequestImpl(
        resourceProvider, offset, _getErrors(offset, result), result);
  }

  List<AnalysisError> _getErrors(int offset, ResolveResult result) {
    LineInfo lineInfo = result.lineInfo;
    int offsetLine = lineInfo.getLocation(offset).lineNumber;
    return result.errors.where((AnalysisError error) {
      int errorLine = lineInfo.getLocation(error.offset).lineNumber;
      return errorLine == offsetLine;
    }).toList();
  }
}

/**
 * A mixin that can be used when creating a subclass of [ServerPlugin] to
 * provide most of the implementation for handling fix 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 FixesMixin implements ServerPlugin {
  /**
   * Return a list containing the fix contributors that should be used to create
   * fixes for the file with the given [path].
   */
  List<FixContributor> getFixContributors(String path);

  /**
   * Return the fixes request that should be passes to the contributors
   * returned from [getFixContributors].
   *
   * Throw a [RequestFailure] if the request could not be created.
   */
  Future<FixesRequest> getFixesRequest(EditGetFixesParams parameters);

  @override
  Future<EditGetFixesResult> handleEditGetFixes(
      EditGetFixesParams parameters) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    String path = parameters.file;
    FixesRequest request = await getFixesRequest(parameters);
    FixGenerator generator = new FixGenerator(getFixContributors(path));
    GeneratorResult<EditGetFixesResult> result =
        await generator.generateFixesResponse(request);
    result.sendNotifications(channel);
    return result.result;
  }
}
