// 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';
import 'package:analyzer/dart/ast/ast.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(classDecl.declaredElement, request);
    } else if (classDecl is MixinDeclaration) {
      return _computeSuggestionsForClass2(classDecl.declaredElement, 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 isFunctionalArgument = request.target.isFunctionalArgument();
    kind = isFunctionalArgument
        ? CompletionSuggestionKind.IDENTIFIER
        : CompletionSuggestionKind.INVOCATION;
    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.of(request.result).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;
    }
  }
}
