/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.codeInsight.completion;

import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.completion.scope.CompletionElement;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.editorActions.wordSelection.DocTagSelectioner;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.SuppressionUtil;
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
import com.intellij.psi.javadoc.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
import com.intellij.util.Processor;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * Created by IntelliJ IDEA.
 * User: ik
 * Date: 05.03.2003
 * Time: 21:40:11
 * To change this template use Options | File Templates.
 */
public class JavaDocCompletionContributor extends CompletionContributor {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaDocCompletionContributor");
  private static final @NonNls String VALUE_TAG = "value";
  private static final @NonNls String LINK_TAG = "link";

  public JavaDocCompletionContributor() {
    extend(CompletionType.BASIC, PsiJavaPatterns.psiElement(JavaDocTokenType.DOC_TAG_NAME), new TagChooser());

    extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocComment.class), new CompletionProvider<CompletionParameters>() {
      @Override
      protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
        final PsiElement position = parameters.getPosition();
        boolean isArg = PsiJavaPatterns.psiElement().afterLeaf("(").accepts(position);
        PsiDocTag tag = PsiTreeUtil.getParentOfType(position, PsiDocTag.class);
        boolean onlyConstants = !isArg && tag != null && tag.getName().equals(VALUE_TAG);

        final PsiReference ref = position.getContainingFile().findReferenceAt(parameters.getOffset());
        if (ref instanceof PsiJavaReference) {
          result.stopHere();

          final JavaCompletionProcessor processor = new JavaCompletionProcessor(position, TrueFilter.INSTANCE, JavaCompletionProcessor.Options.CHECK_NOTHING, Conditions.<String>alwaysTrue());
          ((PsiJavaReference) ref).processVariants(processor);

          for (final CompletionElement _item : processor.getResults()) {
            final Object element = _item.getElement();
            LookupItem item = createLookupItem(element);
            if (onlyConstants) {
              Object o = item.getObject();
              if (!(o instanceof PsiField)) continue;
              PsiField field = (PsiField) o;
              if (!(field.hasModifierProperty(PsiModifier.STATIC) && field.getInitializer() != null &&
                  JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false) != null)) continue;
            }

            item.putUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR, Boolean.TRUE);
            if (isArg) {
              item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
            }
            result.addElement(item);
          }

          JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(position, result));
        }
      }

      private LookupItem createLookupItem(final Object element) {
        if (element instanceof PsiMethod) {
          return new JavaMethodCallElement((PsiMethod)element) {
            @Override
            public void handleInsert(InsertionContext context) {
              new MethodSignatureInsertHandler().handleInsert(context, this);
            }
          };
        }
        if (element instanceof PsiClass) {
          JavaPsiClassReferenceElement classElement = new JavaPsiClassReferenceElement((PsiClass)element);
          classElement.setInsertHandler(JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER);
          return classElement;
        }

        return (LookupItem)LookupItemUtil.objectToLookupItem(element);
      }
    });
  }

  private static PsiParameter getDocTagParam(PsiElement tag) {
    if (tag instanceof PsiDocTag && "param".equals(((PsiDocTag)tag).getName())) {
      PsiDocTagValue value = ((PsiDocTag)tag).getValueElement();
      if (value instanceof PsiDocParamRef) {
        final PsiReference psiReference = value.getReference();
        PsiElement target = psiReference != null ? psiReference.resolve() : null;
        if (target instanceof PsiParameter) {
          return (PsiParameter)target;
        }
      }
    }
    return null;
  }

  @Override
  public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {

    PsiElement position = parameters.getPosition();
    if (PsiJavaPatterns.psiElement(JavaDocTokenType.DOC_COMMENT_DATA).accepts(position)) {
      final PsiParameter param = getDocTagParam(position.getParent());
      if (param != null) {
        suggestSimilarParameterDescriptions(result, position, param);
      }

      return;
    }

    super.fillCompletionVariants(parameters, result);
  }

  private static void suggestSimilarParameterDescriptions(CompletionResultSet result, PsiElement position, final PsiParameter param) {
    final Set<String> descriptions = ContainerUtil.newHashSet();
    position.getContainingFile().accept(new PsiRecursiveElementWalkingVisitor() {
      @Override
      public void visitElement(PsiElement element) {
        PsiParameter param1 = getDocTagParam(element);
        if (param1 != null && param1 != param &&
            Comparing.equal(param1.getName(), param.getName()) && Comparing.equal(param1.getType(), param.getType())) {
          String text = "";
          for (PsiElement psiElement : ((PsiDocTag)element).getDataElements()) {
            if (psiElement != ((PsiDocTag)element).getValueElement()) {
              text += psiElement.getText();
            }
          }
          text = text.trim();
          if (text.contains(" ")) {
            descriptions.add(text);
          }
        }

        super.visitElement(element);
      }
    });
    for (String description : descriptions) {
      result.addElement(LookupElementBuilder.create(description).withInsertHandler(new InsertHandler<LookupElement>() {
        @Override
        public void handleInsert(InsertionContext context, LookupElement item) {
          if (context.getCompletionChar() != Lookup.REPLACE_SELECT_CHAR) return;
          
          context.commitDocument();
          PsiDocTag docTag = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiDocTag.class, false);
          if (docTag != null) {
            Document document = context.getDocument();
            int tagEnd = DocTagSelectioner.getDocTagRange(docTag, document.getCharsSequence(), 0).getEndOffset();
            int tail = context.getTailOffset();
            if (tail < tagEnd) {
              document.deleteString(tail, tagEnd);
            }
          }
        }
      }));
    }
  }

  private static class TagChooser extends CompletionProvider<CompletionParameters> {

    @Override
    protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
      final List<String> ret = new ArrayList<String>();
      final PsiElement position = parameters.getPosition();
      final PsiDocComment comment = PsiTreeUtil.getParentOfType(position, PsiDocComment.class);
      assert comment != null;
      PsiElement parent = comment.getContext();
      if (parent instanceof PsiJavaFile) {
        final PsiJavaFile file = (PsiJavaFile)parent;
        if (PsiPackage.PACKAGE_INFO_FILE.equals(file.getName())) {
          final String packageName = file.getPackageName();
          parent = JavaPsiFacade.getInstance(position.getProject()).findPackage(packageName);
        }
      }

      final boolean isInline = position.getContext() instanceof PsiInlineDocTag;

      for (JavadocTagInfo info : JavadocManager.SERVICE.getInstance(position.getProject()).getTagInfos(parent)) {
        String tagName = info.getName();
        if (tagName.equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue;
        if (isInline != info.isInline()) continue;
        ret.add(tagName);
        addSpecialTags(ret, comment, tagName);
      }

      InspectionProfile inspectionProfile =
        InspectionProjectProfileManager.getInstance(position.getProject()).getInspectionProfile();
      JavaDocLocalInspection inspection =
        (JavaDocLocalInspection)inspectionProfile.getUnwrappedTool(JavaDocLocalInspection.SHORT_NAME, position);
      final StringTokenizer tokenizer = new StringTokenizer(inspection.myAdditionalJavadocTags, ", ");
      while (tokenizer.hasMoreTokens()) {
        ret.add(tokenizer.nextToken());
      }
      for (final String s : ret) {
        if (isInline) {
          result.addElement(LookupElementDecorator.withInsertHandler(LookupElementBuilder.create(s), new InlineInsertHandler()));
        } else {
          result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.INSERT_SPACE));
        }
      }
      result.stopHere(); // no word completions at this point
    }

    private static void addSpecialTags(final List<String> result, PsiDocComment comment, String tagName) {
      if ("author".equals(tagName)) {
        result.add(tagName + " " + SystemProperties.getUserName());
        return;
      }

      if ("param".equals(tagName)) {
        PsiMethod psiMethod = PsiTreeUtil.getParentOfType(comment, PsiMethod.class);
        if (psiMethod != null) {
          PsiDocTag[] tags = comment.getTags();
          for (PsiParameter param : psiMethod.getParameterList().getParameters()) {
            if (!JavaDocLocalInspection.isFound(tags, param)) {
              result.add(tagName + " " + param.getName());
            }
          }
        }
        return;
      }

      if ("see".equals(tagName)) {
        PsiMember member = PsiTreeUtil.getParentOfType(comment, PsiMember.class);
        if (member instanceof PsiClass) {
          InheritanceUtil.processSupers((PsiClass)member, false, new Processor<PsiClass>() {
            @Override
            public boolean process(PsiClass psiClass) {
              String name = psiClass.getQualifiedName();
              if (StringUtil.isNotEmpty(name) && !CommonClassNames.JAVA_LANG_OBJECT.equals(name)) {
                result.add("see " + name);
              }
              return true;
            }
          });
        }
      }
    }
  }

  private static class InlineInsertHandler implements InsertHandler<LookupElement> {
    @Override
    public void handleInsert(InsertionContext context, LookupElement item) {
      if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
        final Project project = context.getProject();
        PsiDocumentManager.getInstance(project).commitAllDocuments();
        final Editor editor = context.getEditor();
        final CaretModel caretModel = editor.getCaretModel();
        final int offset = caretModel.getOffset();
        final PsiElement element = context.getFile().findElementAt(offset - 1);
        PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);

        for (PsiElement child = tag.getFirstChild(); child != null; child = child.getNextSibling()) {
          if (child instanceof PsiDocToken) {
            PsiDocToken token = (PsiDocToken)child;
            if (token.getTokenType() == JavaDocTokenType.DOC_INLINE_TAG_END) return;
          }
        }

        final String name = tag.getName();

        final CharSequence chars = editor.getDocument().getCharsSequence();
        final int currentOffset = caretModel.getOffset();
        if (chars.charAt(currentOffset) == '}') {
          caretModel.moveToOffset(offset + 1);
        }
        else if (chars.charAt(currentOffset + 1) == '}' && chars.charAt(currentOffset) == ' ') {
          caretModel.moveToOffset(offset + 2);
        }
        else if (name.equals(LINK_TAG)) {
          EditorModificationUtil.insertStringAtCaret(editor, " }");
          caretModel.moveToOffset(offset + 1);
          editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
          editor.getSelectionModel().removeSelection();
        }
        else {
          EditorModificationUtil.insertStringAtCaret(editor, "}");
          caretModel.moveToOffset(offset + 1);
        }
      }
    }
  }

  private static class MethodSignatureInsertHandler implements InsertHandler<LookupItem> {
    @Override
    public void handleInsert(InsertionContext context, LookupItem item) {
      if (!(item.getObject() instanceof PsiMethod)) {
        return;
      }
      PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
      final Editor editor = context.getEditor();
      final PsiMethod method = (PsiMethod)item.getObject();

      final PsiParameter[] parameters = method.getParameterList().getParameters();
      final StringBuffer buffer = new StringBuffer();

      final CharSequence chars = editor.getDocument().getCharsSequence();
      int endOffset = editor.getCaretModel().getOffset();
      final Project project = context.getProject();
      int afterSharp = CharArrayUtil.shiftBackwardUntil(chars, endOffset - 1, "#") + 1;
      int signatureOffset = afterSharp;

      PsiElement element = context.getFile().findElementAt(signatureOffset - 1);
      final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(element.getProject());
      PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);
      if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
        final PsiDocTagValue valueElement = tag.getValueElement();
        endOffset = valueElement.getTextRange().getEndOffset();
        context.setTailOffset(endOffset);
      }
      editor.getDocument().deleteString(afterSharp, endOffset);
      editor.getCaretModel().moveToOffset(signatureOffset);
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
      editor.getSelectionModel().removeSelection();
      buffer.append(method.getName() + "(");
      final int afterParenth = afterSharp + buffer.length();
      for (int i = 0; i < parameters.length; i++) {
        final PsiType type = TypeConversionUtil.erasure(parameters[i].getType());
        buffer.append(type.getCanonicalText());

        if (i < parameters.length - 1) {
          buffer.append(",");
          if (styleSettings.SPACE_AFTER_COMMA) buffer.append(" ");
        }
      }
      buffer.append(")");
      if (!(tag instanceof PsiInlineDocTag)) {
        buffer.append(" ");
      }
      else {
        final int currentOffset = editor.getCaretModel().getOffset();
        if (chars.charAt(currentOffset) == '}') {
          afterSharp++;
        }
        else {
          buffer.append("} ");
        }
      }
      String insertString = buffer.toString();
      EditorModificationUtil.insertStringAtCaret(editor, insertString);
      editor.getCaretModel().moveToOffset(afterSharp + buffer.length());
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
      PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());

      shortenReferences(project, editor, context, afterParenth);
    }

    private static void shortenReferences(final Project project, final Editor editor, InsertionContext context, int offset) {
      PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
      final PsiElement element = context.getFile().findElementAt(offset);
      final PsiDocComment docComment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class);
      if (!JavaDocUtil.isInsidePackageInfo(docComment)) {
        final PsiDocTagValue tagValue = PsiTreeUtil.getParentOfType(element, PsiDocTagValue.class);
        if (tagValue != null) {
          try {
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(tagValue);
          }
          catch (IncorrectOperationException e) {
            LOG.error(e);
          }
        }
        PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
      }
    }
  }
}
