// 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/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.of(request.result.session)
            .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;
    }
  }
}
