/*
 * 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 org.jetbrains.plugins.groovy.codeInsight;

import com.intellij.codeInsight.daemon.DaemonBundle;
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper;
import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator;
import com.intellij.codeInsight.daemon.impl.MarkerType;
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask;
import com.intellij.ide.util.MethodCellRenderer;
import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.psi.*;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrTraitMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.text.MessageFormat;
import java.util.*;

/**
 * @author Max Medvedev
 */
public class GroovyMarkerTypes {
  static final MarkerType OVERRIDING_PROPERTY_TYPE = new MarkerType(new Function<PsiElement, String>() {
    @Nullable
    @Override
    public String fun(PsiElement psiElement) {
      final PsiElement parent = psiElement.getParent();
      if (!(parent instanceof GrField)) return null;
      final GrField field = (GrField)parent;

      final List<GrAccessorMethod> accessors = GroovyPropertyUtils.getFieldAccessors(field);
      StringBuilder builder = new StringBuilder();
      builder.append("<html><body>");
      int count = 0;
      String sep = "";
      for (GrAccessorMethod method : accessors) {
        PsiMethod[] superMethods = method.findSuperMethods(false);
        count += superMethods.length;
        if (superMethods.length == 0) continue;
        PsiMethod superMethod = superMethods[0];
        boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
        boolean isSuperAbstract = superMethod.hasModifierProperty(PsiModifier.ABSTRACT);

        @NonNls final String key;
        if (isSuperAbstract && !isAbstract) {
          key = "method.implements.in";
        }
        else {
          key = "method.overrides.in";
        }
        builder.append(sep);
        sep = "<br>";
        composeText(superMethods, DaemonBundle.message(key), builder);
      }
      if (count == 0) return null;
      builder.append("</html></body>");
      return builder.toString();
    }
  }, new LineMarkerNavigator() {
    @Override
    public void browse(MouseEvent e, PsiElement element) {
      PsiElement parent = element.getParent();
      if (!(parent instanceof GrField)) return;
      final GrField field = (GrField)parent;
      final List<GrAccessorMethod> accessors = GroovyPropertyUtils.getFieldAccessors(field);
      final ArrayList<PsiMethod> superMethods = new ArrayList<PsiMethod>();
      for (GrAccessorMethod method : accessors) {
        Collections.addAll(superMethods, method.findSuperMethods(false));
      }
      if (superMethods.isEmpty()) return;
      final PsiMethod[] supers = ContainerUtil.toArray(superMethods, new PsiMethod[superMethods.size()]);
      boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(supers);
      PsiElementListNavigator.openTargets(e, supers, 
                                          DaemonBundle.message("navigation.title.super.method", field.getName()),
                                          DaemonBundle.message("navigation.findUsages.title.super.method", field.getName()),
                                          new MethodCellRenderer(showMethodNames));
    }
  });
  static final MarkerType OVERRIDEN_PROPERTY_TYPE = new MarkerType(new Function<PsiElement, String>() {
    @Nullable
    @Override
    public String fun(PsiElement element) {
      PsiElement parent = element.getParent();
      if (!(parent instanceof GrField)) return null;
      final List<GrAccessorMethod> accessors = GroovyPropertyUtils.getFieldAccessors((GrField)parent);

      PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5);

      for (GrAccessorMethod method : accessors) {
        OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor));
      }
      if (processor.isOverflow()) {
        return DaemonBundle.message("method.is.overridden.too.many");
      }

      PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]);
      if (overridings.length == 0) return null;

      Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator();
      Arrays.sort(overridings, comparator);

      String start = DaemonBundle.message("method.is.overriden.header");
      @NonNls String pattern = "&nbsp;&nbsp;&nbsp;&nbsp;{1}";
      return GutterIconTooltipHelper.composeText(overridings, start, pattern);
    }
  }, new LineMarkerNavigator() {
    @Override
    public void browse(MouseEvent e, PsiElement element) {
      PsiElement parent = element.getParent();
      if (!(parent instanceof GrField)) return;
      if (DumbService.isDumb(element.getProject())) {
        DumbService.getInstance(element.getProject()).showDumbModeNotification("Navigation to overriding classes is not possible during index update");
        return;
      }

      final GrField field = (GrField)parent;


      final CommonProcessors.CollectProcessor<PsiMethod> collectProcessor = new CommonProcessors.CollectProcessor<PsiMethod>(new THashSet<PsiMethod>());
      if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
        @Override
        public void run() {
          ApplicationManager.getApplication().runReadAction(new Runnable() {
            @Override
            public void run() {
              for (GrAccessorMethod method : GroovyPropertyUtils.getFieldAccessors(field)) {
                OverridingMethodsSearch.search(method, true).forEach(collectProcessor);
              }
            }
          });
        }
      }, "Searching for overriding methods", true, field.getProject(), (JComponent)e.getComponent())) {
        return;
      }

      PsiMethod[] overridings = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY);
      if (overridings.length == 0) return;
      String title = DaemonBundle.message("navigation.title.overrider.method", field.getName(), overridings.length);
      boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(overridings);
      MethodCellRenderer renderer = new MethodCellRenderer(showMethodNames);
      Arrays.sort(overridings, renderer.getComparator());
      PsiElementListNavigator.openTargets(e, overridings, title, "Overriding Methods of " + field.getName(), renderer);
    }
  }
  );
  public static final MarkerType OVERRIDING_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() {
      @Override
      public String fun(PsiElement element) {
        PsiElement parent = element.getParent();
        if (!(parent instanceof GrMethod)) return null;
        GrMethod method = (GrMethod)parent;

        Set<PsiMethod> superMethods = collectSuperMethods(method);
        if (superMethods.isEmpty()) return null;

        PsiMethod superMethod = superMethods.iterator().next();
        boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
        boolean isSuperAbstract = superMethod.hasModifierProperty(PsiModifier.ABSTRACT);

        final boolean sameSignature = superMethod.getSignature(PsiSubstitutor.EMPTY).equals(method.getSignature(PsiSubstitutor.EMPTY));
        @NonNls final String key;
        if (isSuperAbstract && !isAbstract){
          key = sameSignature ? "method.implements" : "method.implements.in";
        }
        else{
          key = sameSignature ? "method.overrides" : "method.overrides.in";
        }
        return GutterIconTooltipHelper.composeText(superMethods, "", DaemonBundle.message(key));
      }
    }, new LineMarkerNavigator(){
      @Override
      public void browse(MouseEvent e, PsiElement element) {
        PsiElement parent = element.getParent();
        if (!(parent instanceof GrMethod)) return;
        GrMethod method = (GrMethod)parent;

        Set<PsiMethod> superMethods = collectSuperMethods(method);
        if (superMethods.isEmpty()) return;
        PsiElementListNavigator.openTargets(e, superMethods.toArray(new NavigatablePsiElement[superMethods.size()]),
                    DaemonBundle.message("navigation.title.super.method", method.getName()),
                    DaemonBundle.message("navigation.findUsages.title.super.method", method.getName()),
                    new MethodCellRenderer(true));

      }
    });
  public static final MarkerType OVERRIDEN_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() {
      @Override
      public String fun(PsiElement element) {
        PsiElement parent = element.getParent();
        if (!(parent instanceof GrMethod)) return null;
        GrMethod method = (GrMethod)parent;

        final PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5);

        for (GrMethod m : PsiImplUtil.getMethodOrReflectedMethods(method)) {
          OverridingMethodsSearch.search(m, true).forEach(new ReadActionProcessor<PsiMethod>() {
            @Override
            public boolean processInReadAction(PsiMethod method) {
              if (method instanceof GrTraitMethod) {
                return true;
              }
              return processor.execute(method);
            }
          });
        }

        boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);

        if (processor.isOverflow()){
          return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many");
        }

        PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]);
        if (overridings.length == 0) return null;

        Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator();
        Arrays.sort(overridings, comparator);

        String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header");
        @NonNls String pattern = "&nbsp;&nbsp;&nbsp;&nbsp;{1}";
        return GutterIconTooltipHelper.composeText(overridings, start, pattern);
      }
    }, new LineMarkerNavigator(){
      @Override
      public void browse(MouseEvent e, PsiElement element) {
        PsiElement parent = element.getParent();
        if (!(parent instanceof GrMethod)) return;
        if (DumbService.isDumb(element.getProject())) {
          DumbService.getInstance(element.getProject()).showDumbModeNotification("Navigation to overriding classes is not possible during index update");
          return;
        }


        //collect all overrings (including fields with implicit accessors and method with default parameters)
        final GrMethod method = (GrMethod)parent;
        final PsiElementProcessor.CollectElementsWithLimit<PsiMethod> collectProcessor =
          new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(2, new THashSet<PsiMethod>());
        if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication().runReadAction(new Runnable() {
              @Override
              public void run() {
                for (GrMethod m : PsiImplUtil.getMethodOrReflectedMethods(method)) {
                  OverridingMethodsSearch.search(m, true).forEach(new ReadActionProcessor<PsiMethod>() {
                    @Override
                    public boolean processInReadAction(PsiMethod psiMethod) {
                      if (psiMethod instanceof GrReflectedMethod) {
                        psiMethod = ((GrReflectedMethod)psiMethod).getBaseMethod();
                      }
                      return collectProcessor.execute(psiMethod);
                    }
                  });
                }
              }
            });
          }
        }, MarkerType.SEARCHING_FOR_OVERRIDING_METHODS, true, method.getProject(), (JComponent)e.getComponent())) {
          return;
        }

        PsiMethod[] overridings = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY);
        if (overridings.length == 0) return;

        PsiElementListCellRenderer<PsiMethod> renderer = new MethodCellRenderer(!PsiUtil.allMethodsHaveSameSignature(overridings));
        Arrays.sort(overridings, renderer.getComparator());
        final OverridingMethodsUpdater methodsUpdater = new OverridingMethodsUpdater(method, renderer);
        PsiElementListNavigator.openTargets(e, overridings, methodsUpdater.getCaption(overridings.length),
                                            "Overriding Methods of " + method.getName(),
                                            renderer, methodsUpdater);
        
      }
    });

  private GroovyMarkerTypes() {
  }

  private static Set<PsiMethod> collectSuperMethods(GrMethod method) {
    Set<PsiMethod> superMethods = new HashSet<PsiMethod>();
    for (GrMethod m : PsiImplUtil.getMethodOrReflectedMethods(method)) {
      for (PsiMethod superMethod : m.findSuperMethods(false)) {
        if (superMethod instanceof GrReflectedMethod) {
          superMethod = ((GrReflectedMethod)superMethod).getBaseMethod();
        }

        superMethods.add(superMethod);
      }
    }
    return superMethods;
  }

  private static StringBuilder composeText(@NotNull PsiElement[] elements, final String pattern, StringBuilder result) {
    Set<String> names = new LinkedHashSet<String>();
    for (PsiElement element : elements) {
      String methodName = ((PsiMethod)element).getName();
      PsiClass aClass = ((PsiMethod)element).getContainingClass();
      String className = aClass == null ? "" : ClassPresentationUtil.getNameForClass(aClass, true);
      names.add(MessageFormat.format(pattern, methodName, className));
    }

    @NonNls String sep = "";
    for (String name : names) {
      result.append(sep);
      sep = "<br>";
      result.append(name);
    }
    return result;
  }

  private static class OverridingMethodsUpdater extends ListBackgroundUpdaterTask {
    private final GrMethod myMethod;
    private final PsiElementListCellRenderer myRenderer;

    public OverridingMethodsUpdater(GrMethod method, PsiElementListCellRenderer renderer) {
      super(method.getProject(), MarkerType.SEARCHING_FOR_OVERRIDING_METHODS);
      myMethod = method;
      myRenderer = renderer;
    }

    @Override
    public String getCaption(int size) {
      return myMethod.hasModifierProperty(PsiModifier.ABSTRACT) ?
             DaemonBundle.message("navigation.title.implementation.method", myMethod.getName(), size) :
             DaemonBundle.message("navigation.title.overrider.method", myMethod.getName(), size);
    }

    @Override
    public void run(@NotNull final ProgressIndicator indicator) {
      super.run(indicator);
      for (PsiMethod method : PsiImplUtil.getMethodOrReflectedMethods(myMethod)) {
        OverridingMethodsSearch.search(method, true).forEach(
          new CommonProcessors.CollectProcessor<PsiMethod>() {
            @Override
            public boolean process(PsiMethod psiMethod) {
              if (!updateComponent(com.intellij.psi.impl.PsiImplUtil.handleMirror(psiMethod), myRenderer.getComparator())) {
                indicator.cancel();
              }
              indicator.checkCanceled();
              return true;
            }
          });
      }
    }
  }
}
