// 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.

library services.completion.computer.dart.local;

import 'dart:async';

import 'package:analysis_services/completion/completion_computer.dart';
import 'package:analysis_services/completion/completion_suggestion.dart';
import 'package:analyzer/src/generated/ast.dart';

/**
 * A computer for calculating `completion.getSuggestions` request results
 * for the local library in which the completion is requested.
 */
class LocalComputer extends CompletionComputer {

  @override
  bool computeFast(CompilationUnit unit, AstNode node,
      List<CompletionSuggestion> suggestions) {

    // Find the specific child [AstNode] that contains the completion offset
    // and collect suggestions starting with that node
    if (node != null) {
      node.accept(new _LocalVisitor(offset, suggestions));
    }

    // If the unit is not a part and does not reference any parts
    // then work is complete
    return !unit.directives.any(
        (Directive directive) =>
            directive is PartOfDirective || directive is PartDirective);
  }

  @override
  Future<bool> computeFull(CompilationUnit unit, AstNode node,
      List<CompletionSuggestion> suggestions) {
    // TODO: implement computeFull
    // include results from part files that are included in the library
    return new Future.value(false);
  }
}

/**
 * A visitor for collecting suggestions from the most specific child [AstNode]
 * that contains the completion offset to the [CompilationUnit].
 */
class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
  final int offset;
  final List<CompletionSuggestion> suggestions;

  _LocalVisitor(this.offset, this.suggestions);

  void addSuggestion(SimpleIdentifier id, CompletionSuggestionKind kind) {
    if (id != null) {
      String completion = id.name;
      if (completion != null && completion.length > 0) {
        suggestions.add(
            new CompletionSuggestion(
                kind,
                CompletionRelevance.DEFAULT,
                completion,
                completion.length,
                0,
                false,
                false));
      }
    }
  }

  void addSuggestions(VariableDeclarationList variables,
      CompletionSuggestionKind kind) {
    variables.variables.forEach((VariableDeclaration varDecl) {
      addSuggestion(varDecl.name, kind);
    });
  }

  visitBlock(Block node) {
    node.statements.forEach((Statement stmt) {
      if (stmt.offset < offset) {
        if (stmt is LabeledStatement) {
          stmt.labels.forEach((Label label) {
//            addSuggestion(label.label, CompletionSuggestionKind.LABEL);
          });
        } else if (stmt is VariableDeclarationStatement) {
          stmt.variables.variables.forEach((VariableDeclaration varDecl) {
            if (varDecl.end < offset) {
              addSuggestion(
                  varDecl.name,
                  CompletionSuggestionKind.LOCAL_VARIABLE);
            }
          });
        }
      }
    });
    visitNode(node);
  }

  visitCatchClause(CatchClause node) {
    addSuggestion(node.exceptionParameter, CompletionSuggestionKind.PARAMETER);
    addSuggestion(node.stackTraceParameter, CompletionSuggestionKind.PARAMETER);
    visitNode(node);
  }

  visitClassDeclaration(ClassDeclaration node) {
    node.members.forEach((ClassMember classMbr) {
      if (classMbr is FieldDeclaration) {
        addSuggestions(classMbr.fields, CompletionSuggestionKind.FIELD);
      } else if (classMbr is MethodDeclaration) {
        addSuggestion(classMbr.name, CompletionSuggestionKind.METHOD_NAME);
      }
    });
    visitNode(node);
  }

  visitCompilationUnit(CompilationUnit node) {
    node.directives.forEach((Directive directive) {
      if (directive is ImportDirective) {
        addSuggestion(
            directive.prefix,
            CompletionSuggestionKind.LIBRARY_PREFIX);
      }
    });
    node.declarations.forEach((Declaration declaration) {
      if (declaration is ClassDeclaration) {
        addSuggestion(declaration.name, CompletionSuggestionKind.CLASS);
      } else if (declaration is EnumDeclaration) {
//        addSuggestion(d.name, CompletionSuggestionKind.ENUM);
      } else if (declaration is FunctionDeclaration) {
        addSuggestion(declaration.name, CompletionSuggestionKind.FUNCTION);
      } else if (declaration is TopLevelVariableDeclaration) {
        addSuggestions(
            declaration.variables,
            CompletionSuggestionKind.TOP_LEVEL_VARIABLE);
      } else if (declaration is ClassTypeAlias) {
        addSuggestion(declaration.name, CompletionSuggestionKind.CLASS_ALIAS);
      } else if (declaration is FunctionTypeAlias) {
        addSuggestion(
            declaration.name,
            CompletionSuggestionKind.FUNCTION_TYPE_ALIAS);
      }
    });
  }

  visitForEachStatement(ForEachStatement node) {
    addSuggestion(node.identifier, CompletionSuggestionKind.LOCAL_VARIABLE);
    visitNode(node);
  }

  visitForStatement(ForStatement node) {
    addSuggestions(node.variables, CompletionSuggestionKind.LOCAL_VARIABLE);
    visitNode(node);
  }

  visitFunctionDeclaration(FunctionDeclaration node) {
    // This is added by the compilation unit containing it
    //addSuggestion(node.name, CompletionSuggestionKind.FUNCTION);
    visitNode(node);
  }

  visitFunctionExpression(FunctionExpression node) {
    node.parameters.parameters.forEach((FormalParameter param) {
      addSuggestion(param.identifier, CompletionSuggestionKind.PARAMETER);
    });
    visitNode(node);
  }

  visitMethodDeclaration(MethodDeclaration node) {
    node.parameters.parameters.forEach((FormalParameter param) {
      if (param.identifier != null) {
        addSuggestion(param.identifier, CompletionSuggestionKind.PARAMETER);
      }
    });
    visitNode(node);
  }

  visitNode(AstNode node) {
    node.parent.accept(this);
  }
}
