package com.intellij.ide.util.frameworkSupport;

import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.ui.FacetBasedFrameworkSupportProvider;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportProvider;
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportCommunicator;
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelImpl;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.*;

/**
 * @author nik
 */
public abstract class FrameworkSupportProviderTestCase extends IdeaTestCase {
  private FrameworkSupportModel myFrameworkSupportModel;
  private Map<FrameworkSupportProvider, FrameworkSupportConfigurable> myConfigurables;
  private Set<FrameworkSupportProvider> mySelected;

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    myFrameworkSupportModel = new FrameworkSupportModelImpl(getProject(), null);
    myConfigurables = new HashMap<FrameworkSupportProvider, FrameworkSupportConfigurable>();
    mySelected = new HashSet<FrameworkSupportProvider>();
  }

  protected void addSupport() throws IOException {
    final VirtualFile root = getVirtualFile(createTempDir("contentRoot"));
    PsiTestUtil.addContentRoot(myModule, root);
    final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
    List<FrameworkSupportConfigurable> selectedConfigurables = new ArrayList<FrameworkSupportConfigurable>();
    for (FrameworkSupportProvider provider : mySelected) {
      final FrameworkSupportConfigurable configurable = myConfigurables.get(provider);
      configurable.addSupport(myModule, model, null);
      selectedConfigurables.add(configurable);
    }
    for (FrameworkSupportCommunicator communicator : FrameworkSupportCommunicator.EP_NAME.getExtensions()) {
      communicator.onFrameworkSupportAdded(myModule, model, selectedConfigurables, myFrameworkSupportModel);
    }
    model.commit();
  }

  protected void selectFramework(@NotNull FacetTypeId<?> id) {
    selectFramework(FacetBasedFrameworkSupportProvider.getProviderId(id));
  }

  protected void selectFramework(@NotNull String id) {
    for (FrameworkSupportProvider provider : FrameworkSupportProvider.EXTENSION_POINT.getExtensions()) {
      if (provider.getId().equals(id)) {
        selectFramework(provider);
        return;
      }
    }
    fail("Framework provider with id='" + id + "' not found");
  }

  protected void selectFramework(@NotNull FrameworkSupportProvider provider) {
    final FrameworkSupportConfigurable configurable = getOrCreateConfigurable(provider);
    configurable.onFrameworkSelectionChanged(true);
    mySelected.add(provider);
  }

  private FrameworkSupportConfigurable getOrCreateConfigurable(FrameworkSupportProvider provider) {
    FrameworkSupportConfigurable configurable = myConfigurables.get(provider);
    if (configurable == null) {
      configurable = provider.createConfigurable(myFrameworkSupportModel);
      myConfigurables.put(provider, configurable);
    }
    return configurable;
  }

  protected <F extends Facet> F getFacet(FacetTypeId<F> id) {
    final F facet = FacetManager.getInstance(myModule).getFacetByType(id);
    assertNotNull(id + " facet not found", facet);
    return facet;
  }

  protected VirtualFile getContentRoot() {
    return ModuleRootManager.getInstance(myModule).getContentRoots()[0];
  }
}

@@ -223,225 +223,8 @@
 er;%0A
-import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;%0Aimport com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;%0Aimport com.intellij.ide.util.frameworkSupport.FrameworkSupportProvider;%0A
 impo
@@ -478,32 +478,75 @@
 uleRootManager;%0A
+import com.intellij.openapi.util.Disposer;%0A
 import com.intel
@@ -2254,35 +2254,184 @@
 it();%0A  
-%7D%0A%0A  protected void
+  for (FrameworkSupportConfigurable configurable : myConfigurables.values()) %7B%0A      Disposer.dispose(configurable);%0A    %7D%0A  %7D%0A%0A  protected FrameworkSupportConfigurable
  selectF
@@ -2469,24 +2469,31 @@
 %3E id) %7B%0A    
+return 
 selectFramew
@@ -2560,36 +2560,60 @@
  %7D%0A%0A  protected 
-void
+FrameworkSupportConfigurable
  selectFramework
@@ -2785,24 +2785,31 @@
 ) %7B%0A        
+return 
 selectFramew
@@ -2827,24 +2827,8 @@
 r);%0A
-        return;%0A
     
@@ -2902,35 +2902,76 @@
 nd%22);%0A  
-%7D%0A%0A  protected void
+  return null;%0A  %7D%0A%0A  protected FrameworkSupportConfigurable
  selectF
@@ -3196,16 +3196,41 @@
 vider);%0A
+    return configurable;%0A
   %7D%0A%0A  p

test for app server framework support provider added