// Copyright (c) 2019, 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:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/search/type_hierarchy.dart';

class ImplementationHandler
    extends MessageHandler<TextDocumentPositionParams, List<Location>> {
  ImplementationHandler(LspAnalysisServer server) : super(server);
  @override
  Method get handlesMessage => Method.textDocument_implementation;

  @override
  LspJsonHandler<TextDocumentPositionParams> get jsonHandler =>
      TextDocumentPositionParams.jsonHandler;

  @override
  Future<ErrorOr<List<Location>>> handle(
      TextDocumentPositionParams params, CancellationToken token) async {
    if (!isDartDocument(params.textDocument)) {
      return success(const []);
    }

    final pos = params.position;
    final path = pathOfDoc(params.textDocument);
    final unit = await path.mapResult(requireResolvedUnit);
    final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
    return offset
        .mapResult((offset) => _getImplementations(path.result, offset, token));
  }

  Future<ErrorOr<List<Location>>> _getImplementations(
      String file, int offset, CancelableToken token) async {
    final element = await server.getElementAtOffset(file, offset);
    final computer = TypeHierarchyComputer(server.searchEngine, element);
    if (token.isCancellationRequested) {
      return cancelled();
    }
    final items = await computer.compute();

    if (items == null || items.isEmpty) {
      return success([]);
    }

    Iterable<TypeHierarchyItem> getDescendants(TypeHierarchyItem item) => item
        .subclasses
        ?.map((i) => items[i])
        ?.followedBy(item.subclasses.expand((i) => getDescendants(items[i])));

    // [TypeHierarchyComputer] returns the whole tree, but we specifically only
    // want implementations (sub-classes). Find the referenced element and then
    // recursively add its children.
    var currentItem = items.firstWhere(
      (item) {
        final location =
            item.memberElement?.location ?? item.classElement?.location;
        return location.offset <= offset &&
            location.offset + location.length >= offset;
      },
      // If we didn't find an item spanning our offset, we must've been at a
      // call site so start everything from the root item.
      orElse: () => items.first,
    );

    final isClass = currentItem.memberElement == null;

    final locations = getDescendants(currentItem).where((item) {
      // Filter based on type, so when searching for members we don't include
      // any intermediate classes that don't have implementations for the
      // method.
      return isClass ? item.classElement != null : item.memberElement != null;
    }).map((item) {
      final elementLocation =
          item.memberElement?.location ?? item.classElement?.location;
      final lineInfo = server.getLineInfo(elementLocation.file);
      return Location(
        Uri.file(elementLocation.file).toString(),
        toRange(lineInfo, elementLocation.offset, elementLocation.length),
      );
    }).toList();

    return success(locations);
  }
}
