/*
 * 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.folding.impl;

import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.Language;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.ParameterizedCachedValue;
import com.intellij.psi.util.ParameterizedCachedValueProvider;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

public class FoldingUpdate {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.FoldingUpdate");

  private static final Key<ParameterizedCachedValue<Runnable, Couple<Boolean>>> CODE_FOLDING_KEY = Key.create("code folding");
  private static final Key<String> CODE_FOLDING_FILE_EXTENSION_KEY = Key.create("code folding file extension");

  private static final Comparator<PsiElement> COMPARE_BY_OFFSET = new Comparator<PsiElement>() {
    @Override
    public int compare(PsiElement element, PsiElement element1) {
      int startOffsetDiff = element.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset();
      return startOffsetDiff == 0 ? element.getTextRange().getEndOffset() - element1.getTextRange().getEndOffset() : startOffsetDiff;
    }
  };

  private FoldingUpdate() {
  }

  @Nullable
  static Runnable updateFoldRegions(@NotNull final Editor editor, @NotNull PsiFile file, final boolean applyDefaultState, final boolean quick) {
    ApplicationManager.getApplication().assertReadAccessAllowed();

    final Project project = file.getProject();
    final Document document = editor.getDocument();
    LOG.assertTrue(!PsiDocumentManager.getInstance(project).isUncommited(document));
    
    String currentFileExtension = null;
    final VirtualFile virtualFile = file.getVirtualFile();
    if (virtualFile != null) {
      currentFileExtension = virtualFile.getExtension();
    }

    ParameterizedCachedValue<Runnable, Couple<Boolean>> value = editor.getUserData(CODE_FOLDING_KEY);
    if (value != null) {
      // There was a problem that old fold regions have been cached on file extension change (e.g. *.java -> *.groovy).
      // We want to drop them in such circumstances.
      final String oldExtension = editor.getUserData(CODE_FOLDING_FILE_EXTENSION_KEY);
      if (oldExtension == null ? currentFileExtension != null : !oldExtension.equals(currentFileExtension)) {
        value = null;
        editor.putUserData(CODE_FOLDING_KEY, null);
      }
    }
    editor.putUserData(CODE_FOLDING_FILE_EXTENSION_KEY, currentFileExtension);
    
    if (value != null && value.hasUpToDateValue() && !applyDefaultState) return null;
    if (quick) return getUpdateResult(file, document, quick, project, editor, applyDefaultState).getValue();
    
    return CachedValuesManager.getManager(project).getParameterizedCachedValue(
      editor, CODE_FOLDING_KEY, new ParameterizedCachedValueProvider<Runnable, Couple<Boolean>>() {
        @Override
        public CachedValueProvider.Result<Runnable> compute(Couple<Boolean> param) {
          Document document = editor.getDocument();
          PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
          return getUpdateResult(file, document, param.first, project, editor, param.second);
        }
      }, false, Couple.of(quick, applyDefaultState));
  }

  private static CachedValueProvider.Result<Runnable> getUpdateResult(PsiFile file,
                                                                      @NotNull Document document,
                                                                      boolean quick,
                                                                      final Project project,
                                                                      final Editor editor,
                                                                      final boolean applyDefaultState) {

    final FoldingMap elementsToFoldMap = getFoldingsFor(project, file, document, quick);
    final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, file, elementsToFoldMap, applyDefaultState, false);
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation);
      }
    };
    Set<Object> dependencies = new HashSet<Object>();
    dependencies.add(document);
    for (FoldingDescriptor descriptor : elementsToFoldMap.values()) {
      dependencies.addAll(descriptor.getDependencies());
    }
    return CachedValueProvider.Result.create(runnable, ArrayUtil.toObjectArray(dependencies));
  }

  private static boolean isContentSubstituted(PsiFile file, Project project) {
    final ContentBasedFileSubstitutor[] processors = Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME);
    for (ContentBasedFileSubstitutor processor : processors) {
      if (processor.isApplicable(project, file.getVirtualFile())) {
        return true;
      }
    }
    return false;
  }

  private static final Key<Object> LAST_UPDATE_INJECTED_STAMP_KEY = Key.create("LAST_UPDATE_INJECTED_STAMP_KEY");
  @Nullable
  public static Runnable updateInjectedFoldRegions(@NotNull final Editor editor, @NotNull final PsiFile file, final boolean applyDefaultState) {
    if (file instanceof PsiCompiledElement) return null;
    ApplicationManager.getApplication().assertReadAccessAllowed();

    final Project project = file.getProject();
    Document document = editor.getDocument();
    LOG.assertTrue(!PsiDocumentManager.getInstance(project).isUncommited(document));

    final long timeStamp = document.getModificationStamp();
    Object lastTimeStamp = editor.getUserData(LAST_UPDATE_INJECTED_STAMP_KEY);
    if (lastTimeStamp instanceof Long && ((Long)lastTimeStamp).longValue() == timeStamp) return null;

    List<DocumentWindow> injectedDocuments = InjectedLanguageUtil.getCachedInjectedDocuments(file);
    if (injectedDocuments.isEmpty()) return null;
    final List<EditorWindow> injectedEditors = new ArrayList<EditorWindow>();
    final List<PsiFile> injectedFiles = new ArrayList<PsiFile>();
    final List<FoldingMap> maps = new ArrayList<FoldingMap>();
    for (final DocumentWindow injectedDocument : injectedDocuments) {
      if (!injectedDocument.isValid()) {
        continue;
      }
      InjectedLanguageUtil.enumerate(injectedDocument, file, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
        @Override
        public void visit(@NotNull PsiFile injectedFile, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
          if (!injectedFile.isValid()) return;
          Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
          if (!(injectedEditor instanceof EditorWindow)) return;

          injectedEditors.add((EditorWindow)injectedEditor);
          injectedFiles.add(injectedFile);
          final FoldingMap map = new FoldingMap();
          maps.add(map);
          getFoldingsFor(injectedFile, injectedEditor.getDocument(), map, false);
        }
      });
    }

    return new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < injectedEditors.size(); i++) {
          EditorWindow injectedEditor = injectedEditors.get(i);
          PsiFile injectedFile = injectedFiles.get(i);
          if (!injectedEditor.getDocument().isValid()) continue;
          FoldingMap map = maps.get(i);
          UpdateFoldRegionsOperation op = new UpdateFoldRegionsOperation(project, injectedEditor, injectedFile, map, applyDefaultState, true);
          injectedEditor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(op);
        }

        editor.putUserData(LAST_UPDATE_INJECTED_STAMP_KEY, timeStamp);
      }
    };
  }

  /**
   * Checks the ability to initialize folding in the Dumb Mode. Due to language injections it may depend on
   * edited file and active injections (not yet implemented).
   *
   * @param editor the editor that holds file view
   * @return true  if folding initialization available in the Dumb Mode
   */
  public static boolean supportsDumbModeFolding(@NotNull Editor editor) {
    Project project = editor.getProject();
    if (project != null) {
      PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (file != null) {
        return supportsDumbModeFolding(file);
      }
    }
    return true;
  }

  /**
   * Checks the ability to initialize folding in the Dumb Mode for file.
   *
   * @param file the file to test
   * @return true  if folding initialization available in the Dumb Mode
   */
  public static boolean supportsDumbModeFolding(@NotNull PsiFile file) {
    final FileViewProvider viewProvider = file.getViewProvider();
    for (final Language language : viewProvider.getLanguages()) {
      final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
      if(foldingBuilder != null && !DumbService.isDumbAware(foldingBuilder))
        return false;
    }
    return true;
  }

  static FoldingMap getFoldingsFor(@NotNull Project project, @NotNull PsiFile file, @NotNull Document document, boolean quick) {
    FoldingMap foldingMap = new FoldingMap();
    if (!isContentSubstituted(file, project)) {
      getFoldingsFor(file instanceof PsiCompiledFile ? ((PsiCompiledFile)file).getDecompiledPsiFile() : file, document, foldingMap, quick);
    }
    return foldingMap;
  }

  private static void getFoldingsFor(@NotNull PsiFile file,
                                     @NotNull Document document,
                                     @NotNull FoldingMap elementsToFoldMap,
                                     boolean quick) {
    final FileViewProvider viewProvider = file.getViewProvider();
    TextRange docRange = TextRange.from(0, document.getTextLength());
    for (final Language language : viewProvider.getLanguages()) {
      final PsiFile psi = viewProvider.getPsi(language);
      final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
      if (psi != null && foldingBuilder != null) {
        for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(foldingBuilder, psi, document, quick)) {
          TextRange range = descriptor.getRange();
          if (!docRange.contains(range)) {
            LOG.error("Folding descriptor " + descriptor +
                      " made by " + foldingBuilder +
                      " for " +language +
                      " and called on file " + psi +
                      " is outside document range: " + docRange,
                      ApplicationManager.getApplication().isInternal()
                      ? new Attachment[] {AttachmentFactory.createAttachment(document), new Attachment("psiTree.txt", DebugUtil.psiToString(psi, false, true))}
                      : new Attachment[0]);
          }
          elementsToFoldMap.putValue(descriptor.getElement().getPsi(), descriptor);
        }
      }
    }
  }

  public static class FoldingMap extends MultiMap<PsiElement, FoldingDescriptor>{
    @NotNull
    @Override
    protected Map<PsiElement, Collection<FoldingDescriptor>> createMap() {
      return new TreeMap<PsiElement, Collection<FoldingDescriptor>>(COMPARE_BY_OFFSET);
    }

    @NotNull
    @Override
    protected Collection<FoldingDescriptor> createCollection() {
      return new ArrayList<FoldingDescriptor>(1);
    }
  }
}
