// Copyright (c) 2014, 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/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';

import '../../../protocol_server.dart'
    show CompletionSuggestion, CompletionSuggestionKind;

/**
 * A contributor for calculating prefixed import library member suggestions
 * `completion.getSuggestions` request results.
 */
class LibraryMemberContributor extends DartCompletionContributor {
  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      DartCompletionRequest request) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    // Determine if the target looks like a library prefix
    Expression targetId = request.dotTarget;
    if (targetId is SimpleIdentifier && !request.target.isCascade) {
      Element elem = targetId.staticElement;
      if (elem is PrefixElement && !elem.isSynthetic) {
        LibraryElement containingLibrary = request.libraryElement;
        // Gracefully degrade if the library or directives
        // could not be determined (e.g. detached part file or source change)
        if (containingLibrary != null) {
          List<ImportElement> imports = containingLibrary.imports;
          if (imports != null) {
            return _buildSuggestions(request, elem, containingLibrary, imports);
          }
        }
      }
    }
    return const <CompletionSuggestion>[];
  }

  List<CompletionSuggestion> _buildSuggestions(
      DartCompletionRequest request,
      PrefixElement elem,
      LibraryElement containingLibrary,
      List<ImportElement> imports) {
    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
    for (ImportElement importElem in imports) {
      if (importElem.prefix?.name == elem.name) {
        LibraryElement library = importElem.importedLibrary;
        if (library != null) {
          // Suggest elements from the imported library
          AstNode parent = request.target.containingNode.parent;
          bool isConstructor = parent.parent is ConstructorName;
          bool typesOnly = parent is TypeName;
          bool instCreation = typesOnly && isConstructor;
          LibraryElementSuggestionBuilder builder =
              new LibraryElementSuggestionBuilder(containingLibrary,
                  CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
          for (var element in importElem.namespace.definedNames.values) {
            element.accept(builder);
          }
          suggestions.addAll(builder.suggestions);

          // If the import is 'deferred' then suggest 'loadLibrary'
          if (importElem.isDeferred) {
            FunctionElement loadLibFunct = library.loadLibraryFunction;
            suggestions.add(createSuggestion(loadLibFunct));
          }
        }
      }
    }
    return suggestions;
  }
}
