package com.intellij.refactoring.inline;

import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.psi.PsiCall;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.LightRefactoringTestCase;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import java.util.Iterator;

/**
 * @author yole
 */
public class InlineToAnonymousClassTest extends LightRefactoringTestCase {
  @NotNull
  @Override
  protected String getTestDataPath() {
    return JavaTestUtil.getJavaTestDataPath();
  }

  public void testSimple() throws Exception {
    doTest(false, false);
  }

  public void testChangeToSuperType() throws Exception {
    doTest(false, false);
  }

  public void testImplementsInterface() throws Exception {
    doTest(false, false);
  }

  public void testClassInitializer() throws Exception {
    doTest(false, false);
  }

  public void testConstructor() throws Exception {
    doTest(false, false);
  }

  public void testConstructorWithArguments() throws Exception {
    doTest(false, false);
  }

  public void testConstructorWithArgumentsInExpression() throws Exception {
    doTest(false, false);
  }

  public void testMultipleConstructors() throws Exception {
    doTest(false, false);
  }

  public void testMethodUsage() throws Exception {
    doTest(false, false);
  }

  public void testConstructorArgumentToField() throws Exception {
    doTest(false, false);
  }

  public void testField() throws Exception {
    doTest(false, false);
  }

  public void testStaticConstantField() throws Exception {
    doTest(false, false);
  }

  public void testWritableInitializedField() throws Exception {
    doTest(false, false);
  }

  public void testNullInitializedField() throws Exception {
    doTest(false, false);
  }

  public void testInnerClass() throws Exception {
    doTest(false, false);
  }

  public void testConstructorToInstanceInitializer() throws Exception {
    doTest(false, false);
  }

  public void testNewExpressionContext() throws Exception {
    doTest(false, false);
  }

  public void testWritableFieldInitializedWithParameter() throws Exception {
    doTest(false, false);
  }

  public void testFieldInitializedWithVar() throws Exception {
    doTest(false, false);
  }

  public void testFieldVsLocalConflict() throws Exception {
    doTest(false, false);
  }

  public void testFieldVsParameterConflict() throws Exception {
    doTest(false, false);
  }

  public void testGenerics() throws Exception {
    doTest(false, false);
  }

  public void testGenericsSubstitute() throws Exception {
    doTest(false, false);
  }

  public void testGenericsFieldDeclaration() throws Exception {
    doTest(false, false);
  }

  public void testGenericsRawType() throws Exception {
    doTest(false, false);
  }

  public void testGenericsInTypeParameter() throws Exception {
    doTest(false, false);
  }

  public void testQualifyInner() throws Exception {
    doTest(false, false);
  }

  public void testQualifiedNew() throws Exception {
    doTest(false, false);
  }

  public void testChainedConstructors() throws Exception {
    doTest(false, false);
  }

  public void testChainedVarargConstructors() throws Exception {
    doTest(false, false);
  }

  public void testInlineThisOnly() throws Exception {
    doTest(true, false);
  }

  public void testArrayType() throws Exception {
    doTest(false, false);
  }

  public void testArrayTypeWithGenerics() throws Exception {
    doTest(false, false);
  }

  public void testArrayInitializer() throws Exception {
    doTest(false, false);
  }

  public void testVarargs() throws Exception {
    doTest(false, false);
  }

  public void testSelfReference() throws Exception {
    doTest(false, false);
  }

  public void testOuterClassFieldAccess() throws Exception {
    doTest(false, false);
  }

  public void testPrivateFieldUsedFromInnerClass() throws Exception {
    doTest(false, false);
  }

  public void testOverwriteInitializer() throws Exception {
    doTest(false, false);
  }

  public void testMultipleInnerClasses() throws Exception {
    doTest(false, false);
  }
  
  public void testConstructorArgumentInExpression() throws Exception {
    doTest(false, false);
  }

  public void testMethodCallInNewExpression() throws Exception {
    doTest(false, false);
  }

  public void testMethodCallInNewExpressionWithParens() throws Exception {
    doTest(false, false);
  }

  public void testRedundantImplementsInterface() throws Exception {
    doTest(false, false);
  }

  public void testStringInMethodCallFromConstructor() throws Exception {
    doTest(false, false);
  }

  public void testMultipleGeneratedVars() throws Exception {
    doTest(false, false);
  }

  public void testFieldAsConstructorParameter() throws Exception {
    doTest(false, false);
  }

  public void testQualifyParentStaticReferences() throws Exception {
    doTest(false, false);
  }

  public void testLocalClass() throws Exception {
    doTest(false, true);
  }

  public void testMultipleAssignments() throws Exception {
    doTest(false, true);
  }

  public void testParamTypeReplacement() throws Exception {
    doTest(false, true);
  }

  public void testBraces() throws Exception {
    doTest(false, false);
  }

  public void testAvailableInSupers() throws Exception {
    doTest(false, false);
  }
  
  public void testNoInlineAbstract() throws Exception {
    doTestNoInline("Abstract classes cannot be inlined");
  }

  public void testNoInlineInterface() throws Exception {
    doTestNoInline("Interfaces cannot be inlined");
  }

  public void testNoInlineEnum() throws Exception {
    doTestNoInline("Enums cannot be inlined");
  }

  public void testNoInlineAnnotationType() throws Exception {
    doTestNoInline("Annotation types cannot be inlined");
  }

  public void testNoInlineMultipleInterfaces() throws Exception {
    doTestNoInline("Classes which implement multiple interfaces cannot be inlined");
  }

  public void testNoInlineSuperclassInterface() throws Exception {
    doTestNoInline("Classes which have a superclass and implement an interface cannot be inlined");
  }

  public void testNoInlineMethodUsage() throws Exception {
    doTestNoInline("Class cannot be inlined because it has usages of methods not inherited from its superclass or interface");
  }

  public void testNoInlineFieldUsage() throws Exception {
    doTestNoInline("Class cannot be inlined because it has usages of fields not inherited from its superclass");
  }

  public void testNoInlineNewWithInner() throws Exception {
    doTestNoInline("Class cannot be inlined because it has usages of its inner classes");
  }

  public void testNoInlineStaticField() throws Exception {
    doTestNoInline("Class cannot be inlined because it has static fields with non-constant initializers");
  }

  public void testNoInlineStaticNonFinalField() throws Exception {
    doTestNoInline("Class cannot be inlined because it has static non-final fields");
  }

  public void testNoInlineStaticMethod() throws Exception {
    doTestNoInline("Class cannot be inlined because it has static methods");
  }

  public void testNoInlineStaticInitializer() throws Exception {
    doTestNoInline("Class cannot be inlined because it has static initializers");
  }

  public void testNoInlineClassLiteral() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because it has usages of its class literal");
  }

  public void testNoInlineCatchClause() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because it is used in a 'catch' clause");
  }

  public void testNoInlineThrowsClause() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because it is used in a 'throws' clause");
  }

  public void testNoInlineThisQualifier() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because it is used as a 'this' qualifier");
  }

  public void testNoInlineUnresolvedConstructor() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because a call to its constructor is unresolved");
  }

  public void testNoInlineUnresolvedConstructor2() throws Exception {
    doTestPreprocessUsages("Class cannot be inlined because a call to its constructor is unresolved");
  }

  public void testNoInlineStaticInnerClass() throws Exception {
    doTestNoInline("Class cannot be inlined because it has static inner classes");
  }

  public void testNoInlineReturnInConstructor() throws Exception {
    doTestNoInline("Class cannot be inlined because its constructor contains 'return' statements");
  }

  public void testNoInlineUnresolvedSuperclass() throws Exception {
    doTestNoInline("Class cannot be inlined because its superclass cannot be resolved");
  }

  public void testNoInlineUnresolvedInterface() throws Exception {
    doTestNoInline("Class cannot be inlined because an interface implemented by it cannot be resolved");
  }

  public void testNoInlineLibraryClass() throws Exception {
    doTestNoInline("Library classes cannot be inlined");
  }

  public void testNoInlineNoUsages() throws Exception {
    doTestPreprocessUsages("Class is never used");
  }

  public void testNoInlineRecursiveAccess() throws Exception {
    doTestConflict("Class cannot be inlined because a call to its member inside body", "Class cannot be inlined because a call to its member inside body");
  }

  public void testConflictInaccessibleOuterField() throws Exception {
    doTestConflict(
      "Field <b><code>C2.a</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>C2User.test()</code></b>");
  }

  public void testGetClassConflict() throws Exception {
    doTestConflict("Result of getClass() invocation would be changed", "Result of getClass() invocation would be changed");
  }

  public void doTestConflict(final String... expected) throws Exception {
    InlineToAnonymousClassProcessor processor = prepareProcessor();
    UsageInfo[] usages = processor.findUsages();
    MultiMap<PsiElement,String> conflicts = processor.getConflicts(usages);
    assertEquals(expected.length, conflicts.size());
    final Iterator<? extends String> iterator = conflicts.values().iterator();
    for (String s : expected) {
      assertTrue(iterator.hasNext());
      assertEquals(s, iterator.next());
    }
  }

  private void doTestNoInline(final String expectedMessage) throws Exception {
    String name = getTestName(false);
    @NonNls String fileName = "/refactoring/inlineToAnonymousClass/" + name + ".java";
    configureByFile(fileName);
    PsiElement element = TargetElementUtilBase
      .findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
    assertInstanceOf(element, PsiClass.class);

    String message = InlineToAnonymousClassHandler.getCannotInlineMessage((PsiClass) element);
    assertEquals(expectedMessage, message);
  }

  private void doTest(final boolean inlineThisOnly, final boolean searchInNonJavaFiles) throws Exception {
    String name = getTestName(false);
    @NonNls String fileName = "/refactoring/inlineToAnonymousClass/" + name + ".java";
    configureByFile(fileName);
    performAction(inlineThisOnly, searchInNonJavaFiles);
    checkResultByFile(null, fileName + ".after", true);
  }

  private void doTestPreprocessUsages(final String expectedMessage) throws Exception {
    configureByFile("/refactoring/inlineToAnonymousClass/" + getTestName(false) + ".java");
    PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase
      .ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
    assertInstanceOf(element, PsiClass.class);
    final PsiClass psiClass = (PsiClass)element;
    assertEquals(expectedMessage, InlineToAnonymousClassHandler.getCannotInlineMessage(psiClass));
  }

  private InlineToAnonymousClassProcessor prepareProcessor() throws Exception {
    String name = getTestName(false);
    @NonNls String fileName = "/refactoring/inlineToAnonymousClass/" + name + ".java";
    configureByFile(fileName);
    PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase
      .ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
    assertInstanceOf(element, PsiClass.class);

    assertEquals(null, InlineToAnonymousClassHandler.getCannotInlineMessage((PsiClass) element));
    return new InlineToAnonymousClassProcessor(getProject(), (PsiClass) element, null, false, false, false);
  }

  private void performAction(final boolean inlineThisOnly, final boolean searchInNonJavaFiles) {
    PsiElement element = TargetElementUtilBase
      .findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
    PsiCall callToInline = InlineToAnonymousClassHandler.findCallToInline(myEditor);
    PsiClass classToInline = (PsiClass) element;
    assertEquals(null, InlineToAnonymousClassHandler.getCannotInlineMessage(classToInline));
    final InlineToAnonymousClassProcessor processor = new InlineToAnonymousClassProcessor(getProject(), classToInline, callToInline, inlineThisOnly,
                                                                                          false, searchInNonJavaFiles);
    UsageInfo[] usages = processor.findUsages();
    MultiMap<PsiElement, String> conflicts = processor.getConflicts(usages);
    assertEquals(0, conflicts.size());
    processor.run();
  }

  public void testCanBeInvokedOnReference() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  public void testCanBeInvokedOnReference1() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  public void testCanBeInvokedOnReferenceSubstitution() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  public void testCanBeInvokedOnReferenceSubstitution1() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  public void testCanBeInvokedOnReferenceVarargs() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  public void testCantBeInvokedOnReference() throws Exception {
    doTestCanBeInvokedOnReference(false);
  }

  public void testCantBeInvokedOnReference1() throws Exception {
    doTestCanBeInvokedOnReference(false);
  }

  public void testCantBeInvokedOnReferenceReturnStatement() throws Exception {
    doTestCanBeInvokedOnReference(false);
  }

  public void testCanBeInvokedOnReferenceSyncStatement() throws Exception {
    doTestCanBeInvokedOnReference(true);
  }

  private void doTestCanBeInvokedOnReference(boolean canBeInvokedOnReference) throws Exception {
    configureByFile("/refactoring/inlineToAnonymousClass/" + getTestName(false) + ".java");
    PsiElement element = TargetElementUtilBase
      .findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
    PsiCall callToInline = InlineToAnonymousClassHandler.findCallToInline(myEditor);
    PsiClass classToInline = (PsiClass) element;
    assertEquals(null, InlineToAnonymousClassHandler.getCannotInlineMessage(classToInline));
    final PsiClassType superType = InlineToAnonymousClassProcessor.getSuperType(classToInline);
    assertTrue(superType != null);
    assertEquals(canBeInvokedOnReference, InlineToAnonymousClassHandler.canBeInvokedOnReference(callToInline, superType));
  }
}