/*
 * Copyright 2000-2013 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.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.diagnostic.LogEventException;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.FileASTNode;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.RangeMarkerEx;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.DebugUtil;

import java.util.List;

/**
 * @author peter
 */
class CompletionAssertions {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CompletionAssertions");

  static void assertCommitSuccessful(Editor editor, PsiFile psiFile) {
    Document document = editor.getDocument();
    int docLength = document.getTextLength();
    int psiLength = psiFile.getTextLength();
    PsiDocumentManager manager = PsiDocumentManager.getInstance(psiFile.getProject());
    boolean committed = !manager.isUncommited(document);
    if (docLength == psiLength && committed) {
      return;
    }

    String message = "unsuccessful commit:";
    message += "\nmatching=" + (psiFile == manager.getPsiFile(document));
    message += "\ninjectedEditor=" + (editor instanceof EditorWindow);
    message += "\ninjectedFile=" + InjectedLanguageManager.getInstance(psiFile.getProject()).isInjectedFragment(psiFile);
    message += "\ncommitted=" + committed;
    message += "\nfile=" + psiFile.getName();
    message += "\nfile class=" + psiFile.getClass();
    message += "\nfile.valid=" + psiFile.isValid();
    message += "\nlanguage=" + psiFile.getLanguage();
    message += "\ndoc.length=" + docLength;
    message += "\npsiFile.length=" + psiLength;
    String fileText = psiFile.getText();
    if (fileText != null) {
      message += "\npsiFile.text.length=" + fileText.length();
    }
    FileASTNode node = psiFile.getNode();
    if (node != null) {
      message += "\nnode.length=" + node.getTextLength();
      String nodeText = node.getText();
      if (nodeText != null) {
        message += "\nnode.text.length=" + nodeText.length();
      }
    }
    message += "\n" + DebugUtil.currentStackTrace();

    throw new LogEventException("Commit unsuccessful", message,
                                       new Attachment(psiFile.getViewProvider().getVirtualFile().getPath() + "_file.txt", fileText),
                                       createAstAttachment(psiFile, psiFile),
                                       new Attachment("docText.txt", document.getText()));
  }

  static void checkEditorValid(Editor editor) {
    if (editor instanceof EditorWindow && !((EditorWindow)editor).isValid()) {
      throw new AssertionError();
    }
  }

  private static Attachment createAstAttachment(PsiFile fileCopy, final PsiFile originalFile) {
    return new Attachment(originalFile.getViewProvider().getVirtualFile().getPath() + " syntactic tree.txt", DebugUtil.psiToString(fileCopy, false, true));
  }

  private static Attachment createFileTextAttachment(PsiFile fileCopy, final PsiFile originalFile) {
    return new Attachment(originalFile.getViewProvider().getVirtualFile().getPath(), fileCopy.getText());
  }

  static void assertFinalOffsets(PsiFile originalFile, CompletionContext context, PsiFile injected) {
    if (context.getStartOffset() >= context.file.getTextLength()) {
      String msg = "start outside the file; file=" + context.file + " " + context.file.getTextLength();
      msg += "; injected=" + (injected != null);
      msg += "; original " + originalFile + " " + originalFile.getTextLength();
      throw new AssertionError(msg);
    }
    assert context.getStartOffset() >= 0 : "start < 0";
  }

  static void assertInjectedOffsets(int hostStartOffset,
                                    InjectedLanguageManager injectedLanguageManager,
                                    PsiFile injected,
                                    DocumentWindow documentWindow) {
    assert documentWindow != null : "no DocumentWindow for an injected fragment";

    TextRange host = injectedLanguageManager.injectedToHost(injected, injected.getTextRange());
    assert hostStartOffset >= host.getStartOffset() : "startOffset before injected";
    assert hostStartOffset <= host.getEndOffset() : "startOffset after injected";
  }

  static void assertHostInfo(PsiFile hostCopy, OffsetMap hostMap) {
    assert hostCopy.isValid() : "file became invalid: " + hostCopy.getClass();
    if (hostMap.getOffset(CompletionInitializationContext.START_OFFSET) >= hostCopy.getTextLength()) {
      throw new AssertionError("startOffset outside the host file: " + hostMap.getOffset(CompletionInitializationContext.START_OFFSET) + "; " + hostCopy);
    }
  }

  static void assertCompletionPositionPsiConsistent(CompletionContext newContext,
                                                    int offset,
                                                    PsiFile fileCopy,
                                                    PsiFile originalFile, PsiElement insertedElement) {
    if (insertedElement == null) {
      throw new LogEventException("No element at insertion offset",
                                                                   "offset=" +
                                                                   newContext.getStartOffset() +
                                                                   "\n" +
                                                                   DebugUtil.currentStackTrace(),
                                                                   createFileTextAttachment(fileCopy, originalFile),
                                                                   createAstAttachment(fileCopy, originalFile));
    }

    if (fileCopy.findElementAt(offset) != insertedElement) {
      throw new AssertionError("wrong offset");
    }

    final TextRange range = insertedElement.getTextRange();
    String fileCopyText = fileCopy.getText();
    if ((range.getEndOffset() > fileCopyText.length()) || !range.substring(fileCopyText).equals(insertedElement.getText())) {
      throw new LogEventException("Inconsistent completion tree", "range=" + range + "\n" + DebugUtil.currentStackTrace(),
                                         createFileTextAttachment(fileCopy, originalFile), createAstAttachment(fileCopy, originalFile),
                                         new Attachment("Element at caret.txt", insertedElement.getText()));
    }
  }

  static class WatchingInsertionContext extends InsertionContext {
    private RangeMarkerEx tailWatcher;
    String invalidateTrace;
    DocumentEvent killer;
    private RangeMarkerSpy spy;

    public WatchingInsertionContext(CompletionProgressIndicator indicator, char completionChar, List<LookupElement> items, Editor editor) {
      super(indicator.getOffsetMap(), completionChar, items.toArray(new LookupElement[items.size()]),
            indicator.getParameters().getOriginalFile(), editor,
            completionChar != Lookup.AUTO_INSERT_SELECT_CHAR && completionChar != Lookup.REPLACE_SELECT_CHAR &&
            completionChar != Lookup.NORMAL_SELECT_CHAR);
    }

    @Override
    public void setTailOffset(int offset) {
      super.setTailOffset(offset);
      watchTail(offset);
    }

    private void watchTail(int offset) {
      stopWatching();
      tailWatcher = (RangeMarkerEx)getDocument().createRangeMarker(offset, offset);
      if (!tailWatcher.isValid()) {
        throw new AssertionError(getDocument() + "; offset=" + offset);
      }
      tailWatcher.setGreedyToRight(true);
      spy = new RangeMarkerSpy(tailWatcher) {
        @Override
        protected void invalidated(DocumentEvent e) {
          if (ApplicationManager.getApplication().isUnitTestMode()) {
            LOG.error("Tail offset invalidated, say thanks to the "+ e);
          }

          if (invalidateTrace == null) {
            invalidateTrace = DebugUtil.currentStackTrace();
            killer = e;
          }
        }
      };
      getDocument().addDocumentListener(spy);
    }

    void stopWatching() {
      if (tailWatcher != null) {
        getDocument().removeDocumentListener(spy);
        tailWatcher.dispose();
      }
    }

    @Override
    public int getTailOffset() {
      int offset = super.getTailOffset();
      if (tailWatcher.getStartOffset() != tailWatcher.getEndOffset() && offset > 0) {
        watchTail(offset);
      }

      return offset;
    }
  }
}
