
package com.intellij.slicer;

import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class JavaSliceProvider implements SliceLanguageSupportProvider {
  @NotNull
  @Override
  public SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
    return JavaSliceUsage.createRootUsage(element, params);
  }

  @Nullable
  @Override
  public PsiElement getExpressionAtCaret(PsiElement atCaret, boolean dataFlowToThis) {
    PsiElement element = PsiTreeUtil.getParentOfType(atCaret, PsiExpression.class, PsiVariable.class);
    if (dataFlowToThis && element instanceof PsiLiteralExpression) return null;
    return element;
  }

  @NotNull
  @Override
  public PsiElement getElementForDescription(@NotNull PsiElement element) {
    if (element instanceof PsiReferenceExpression) {
      PsiElement elementToSlice = ((PsiReferenceExpression)element).resolve();
      if (elementToSlice != null) {
        return elementToSlice;
      }
    }
    return element;
  }

  @NotNull
  @Override
  public SliceUsageCellRendererBase getRenderer() {
    return new SliceUsageCellRenderer();
  }

  @Override
  public void startAnalyzeLeafValues(AbstractTreeStructure structure, Runnable finalRunnable) {
    SliceLeafAnalyzer.startAnalyzeValues(structure, finalRunnable);
  }

  @Override
  public void startAnalyzeNullness(AbstractTreeStructure structure, Runnable finalRunnable) {
    SliceNullnessAnalyzer.startAnalyzeNullness(structure, finalRunnable);
  }

  @Override
  public void registerExtraPanelActions(DefaultActionGroup actionGroup, SliceTreeBuilder sliceTreeBuilder) {
    if (sliceTreeBuilder.dataFlowToThis) {
      actionGroup.add(new GroupByLeavesAction(sliceTreeBuilder));
      actionGroup.add(new CanItBeNullAction(sliceTreeBuilder));
    }
  }
}
