// 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);
  Method get handlesMessage => Method.textDocument_implementation;

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

  @override
  Future<ErrorOr<List<Location>>> handle(
      TextDocumentPositionParams params) 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));
  }

  Future<ErrorOr<List<Location>>> _getImplementations(
      String file, int offset) async {
    final element = await server.getElementAtOffset(file, offset);
    final computer = new TypeHierarchyComputer(server.searchEngine, element);
    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);
  }
}
