// 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:analysis_server/src/utilities/flutter.dart' as flutter;
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';

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

/**
 * Return the class containing the target
 * or `null` if the target is in a static method or field
 * or not in a class.
 */
ClassOrMixinDeclaration _enclosingClass(CompletionTarget target) {
  AstNode node = target.containingNode;
  while (node != null) {
    if (node is ClassOrMixinDeclaration) {
      return node;
    } else if (node is MethodDeclaration) {
      if (node.isStatic) {
        return null;
      }
    } else if (node is FieldDeclaration) {
      if (node.isStatic) {
        return null;
      }
    }
    node = node.parent;
  }
  return null;
}

/**
 * A contributor for calculating suggestions for inherited references.
 */
class InheritedReferenceContributor extends DartCompletionContributor
    with ElementSuggestionBuilder {
  @override
  LibraryElement containingLibrary;

  @override
  CompletionSuggestionKind kind;

  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      DartCompletionRequest request) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    if (!request.includeIdentifiers) {
      return const <CompletionSuggestion>[];
    }

    ClassOrMixinDeclaration classDecl = _enclosingClass(request.target);
    if (classDecl == null || classDecl.declaredElement == null) {
      return const <CompletionSuggestion>[];
    }
    containingLibrary = request.libraryElement;
    if (classDecl is ClassDeclaration) {
      return _computeSuggestionsForClass2(
          resolutionMap.elementDeclaredByClassDeclaration(classDecl), request);
    } else if (classDecl is MixinDeclaration) {
      return _computeSuggestionsForClass2(
          resolutionMap.elementDeclaredByMixinDeclaration(classDecl), request);
    }
    return const <CompletionSuggestion>[];
  }

  _addSuggestionsForType(InterfaceType type, DartCompletionRequest request,
      {bool isFunctionalArgument: false}) {
    OpType opType = request.opType;
    if (!isFunctionalArgument) {
      for (PropertyAccessorElement elem in type.accessors) {
        if (elem.isGetter) {
          if (opType.includeReturnValueSuggestions) {
            addSuggestion(elem);
          }
        } else {
          if (opType.includeVoidReturnSuggestions) {
            addSuggestion(elem);
          }
        }
      }
    }
    for (MethodElement elem in type.methods) {
      if (elem.returnType == null) {
        addSuggestion(elem);
      } else if (!elem.returnType.isVoid) {
        if (opType.includeReturnValueSuggestions) {
          addSuggestion(elem);
        }
      } else {
        if (opType.includeVoidReturnSuggestions) {
          CompletionSuggestion suggestion = addSuggestion(elem);
          _updateFlutterSuggestions(request, elem, suggestion);
        }
      }
    }
  }

  List<CompletionSuggestion> _computeSuggestionsForClass2(
      ClassElement classElement, DartCompletionRequest request,
      {bool skipChildClass: true}) {
    bool isFunctionalArgument = request.target.isFunctionalArgument();
    kind = isFunctionalArgument
        ? CompletionSuggestionKind.IDENTIFIER
        : CompletionSuggestionKind.INVOCATION;
    if (!skipChildClass) {
      _addSuggestionsForType(classElement.type, request,
          isFunctionalArgument: isFunctionalArgument);
    }

    for (InterfaceType type in classElement.allSupertypes) {
      _addSuggestionsForType(type, request,
          isFunctionalArgument: isFunctionalArgument);
    }
    return suggestions;
  }

  void _updateFlutterSuggestions(DartCompletionRequest request, Element element,
      CompletionSuggestion suggestion) {
    if (suggestion == null) {
      return;
    }
    if (element is MethodElement &&
        element.name == 'setState' &&
        flutter.isExactState(element.enclosingElement)) {
      // Find the line indentation.
      String content = request.result.content;
      int lineStartOffset = request.offset;
      int notWhitespaceOffset = request.offset;
      for (; lineStartOffset > 0; lineStartOffset--) {
        var char = content.substring(lineStartOffset - 1, lineStartOffset);
        if (char == '\n') {
          break;
        }
        if (char != ' ' && char != '\t') {
          notWhitespaceOffset = lineStartOffset - 1;
        }
      }
      String indent = content.substring(lineStartOffset, notWhitespaceOffset);

      // Let the user know that we are going to insert a complete statement.
      suggestion.displayText = 'setState(() {});';

      // Build the completion and the selection offset.
      var buffer = new StringBuffer();
      buffer.writeln('setState(() {');
      buffer.write('$indent  ');
      suggestion.selectionOffset = buffer.length;
      buffer.writeln();
      buffer.write('$indent});');
      suggestion.completion = buffer.toString();

      // There are no arguments to fill.
      suggestion.parameterNames = null;
      suggestion.parameterTypes = null;
      suggestion.requiredParameterCount = null;
      suggestion.hasNamedParameters = null;
    }
  }
}
