// 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 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart' show Source, UriKind;
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    hide Element, ElementKind;
import 'package:analyzer_plugin/src/utilities/documentation.dart';
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
import 'package:analyzer_plugin/utilities/completion/relevance.dart';
import 'package:analyzer_plugin/utilities/completion/suggestion_builder.dart';

/**
 * An object used to build code completion suggestions for Dart code.
 */
class SuggestionBuilderImpl implements SuggestionBuilder {
  /**
   * The resource provider used to access the file system.
   */
  final ResourceProvider resourceProvider;

  /**
   * The converter used to convert analyzer objects to protocol objects.
   */
  final AnalyzerConverter converter = new AnalyzerConverter();

  /**
   * Initialize a newly created suggestion builder.
   */
  SuggestionBuilderImpl(this.resourceProvider);

  /**
   * Add default argument list text and ranges based on the given [requiredParams]
   * and [namedParams].
   */
  void addDefaultArgDetails(
      CompletionSuggestion suggestion,
      Element element,
      Iterable<ParameterElement> requiredParams,
      Iterable<ParameterElement> namedParams) {
    // Copied from analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
    StringBuffer buffer = new StringBuffer();
    List<int> ranges = <int>[];

    int offset;

    for (ParameterElement param in requiredParams) {
      if (buffer.isNotEmpty) {
        buffer.write(', ');
      }
      offset = buffer.length;
      String name = param.name;
      buffer.write(name);
      ranges.addAll([offset, name.length]);
    }

    for (ParameterElement param in namedParams) {
      if (param.hasRequired) {
        if (buffer.isNotEmpty) {
          buffer.write(', ');
        }
        String name = param.name;
        buffer.write('$name: ');
        offset = buffer.length;
        String defaultValue = 'null'; // originally _getDefaultValue(param)
        buffer.write(defaultValue);
        ranges.addAll([offset, defaultValue.length]);
      }
    }

    suggestion.defaultArgumentListString =
        buffer.isNotEmpty ? buffer.toString() : null;
    suggestion.defaultArgumentListTextRanges =
        ranges.isNotEmpty ? ranges : null;
  }

  @override
  CompletionSuggestion forElement(Element element,
      {String completion,
      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
      int relevance: DART_RELEVANCE_DEFAULT,
      Source importForSource}) {
    // Copied from analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
    if (element == null) {
      return null;
    }
    if (element is ExecutableElement && element.isOperator) {
      // Do not include operators in suggestions
      return null;
    }
    if (completion == null) {
      completion = element.displayName;
    }
    bool isDeprecated = element.hasDeprecated;
    CompletionSuggestion suggestion = new CompletionSuggestion(
        kind,
        isDeprecated ? DART_RELEVANCE_LOW : relevance,
        completion,
        completion.length,
        0,
        isDeprecated,
        false);

    // Attach docs.
    String doc = removeDartDocDelimiters(element.documentationComment);
    suggestion.docComplete = doc;
    suggestion.docSummary = getDartDocSummary(doc);

    suggestion.element = converter.convertElement(element);
    Element enclosingElement = element.enclosingElement;
    if (enclosingElement is ClassElement) {
      suggestion.declaringType = enclosingElement.displayName;
    }
    suggestion.returnType = getReturnTypeString(element);
    if (element is ExecutableElement && element is! PropertyAccessorElement) {
      suggestion.parameterNames = element.parameters
          .map((ParameterElement parameter) => parameter.name)
          .toList();
      suggestion.parameterTypes =
          element.parameters.map((ParameterElement parameter) {
        DartType paramType = parameter.type;
        // Gracefully degrade if type not resolved yet
        return paramType != null ? paramType.displayName : 'var';
      }).toList();

      Iterable<ParameterElement> requiredParameters = element.parameters
          .where((ParameterElement param) => param.isNotOptional);
      suggestion.requiredParameterCount = requiredParameters.length;

      Iterable<ParameterElement> namedParameters =
          element.parameters.where((ParameterElement param) => param.isNamed);
      suggestion.hasNamedParameters = namedParameters.isNotEmpty;

      addDefaultArgDetails(
          suggestion, element, requiredParameters, namedParameters);
    }
    if (importForSource != null) {
      String srcPath =
          resourceProvider.pathContext.dirname(importForSource.fullName);
      LibraryElement libElem = element.library;
      if (libElem != null) {
        Source libSource = libElem.source;
        if (libSource != null) {
          UriKind uriKind = libSource.uriKind;
          if (uriKind == UriKind.DART_URI) {
            suggestion.importUri = libSource.uri.toString();
          } else if (uriKind == UriKind.PACKAGE_URI) {
            suggestion.importUri = libSource.uri.toString();
          } else if (uriKind == UriKind.FILE_URI &&
              element.source.uriKind == UriKind.FILE_URI) {
            try {
              suggestion.importUri = resourceProvider.pathContext
                  .relative(libSource.fullName, from: srcPath);
            } catch (_) {
              // ignored
            }
          }
        }
      }
      if (suggestion.importUri == null) {
        // Do not include out of scope suggestions
        // for which we cannot determine an import
        return null;
      }
    }
    return suggestion;
  }

  String getReturnTypeString(Element element) {
    // Copied from analysis_server/lib/src/protocol_server.dart
    if (element is ExecutableElement) {
      if (element.kind == ElementKind.SETTER) {
        return null;
      } else {
        return element.returnType?.toString();
      }
    } else if (element is VariableElement) {
      DartType type = element.type;
      return type != null ? type.displayName : 'dynamic';
    } else if (element is FunctionTypeAliasElement) {
      return element.returnType.toString();
    } else {
      return null;
    }
  }
}
