// Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).

package com.twitter.intellij.pants.components.impl;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.ArrayUtil;
import com.twitter.intellij.pants.components.PantsProjectCache;
import com.twitter.intellij.pants.testFramework.PantsCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

public class PantsProjectCacheTest extends PantsCodeInsightFixtureTestCase {
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    ApplicationManager.getApplication().runWriteAction(
      new Runnable() {
        @Override
        public void run() {
          final ModifiableRootModel modifiableRootModel = ModuleRootManager.getInstance(getModule()).getModifiableModel();
          for (ContentEntry contentEntry : modifiableRootModel.getContentEntries()) {
            final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
            for (SourceFolder sourceFolder : sourceFolders) {
              contentEntry.removeSourceFolder(sourceFolder);
            }
          }
          modifiableRootModel.commit();
        }
      }
    );
    PantsProjectCacheImpl.getInstance(getProject()).projectOpened();
  }

  @Override
  protected void tearDown() throws Exception {
    PantsProjectCacheImpl.getInstance(getProject()).projectClosed();
    try {
      super.tearDown();
    }
    catch (Exception e) {
      // TODO: something in the test framework isn't disposed.
      if (!e.getMessage().contains("hasn't been disposed")) {
        throw e;
      }
    }
  }

  @NotNull
  public VirtualFile getMainContentRoot() {
    final VirtualFile result = ArrayUtil.getFirstElement(ModuleRootManager.getInstance(getModule()).getContentRoots());
    assertNotNull(result);
    return result;
  }

  public void testEmpty() {
    final PantsProjectCache cache = PantsProjectCacheImpl.getInstance(myFixture.getProject());
    assertFalse(cache.folderContainsSourceRoot(myFixture.getProject().getBaseDir()));
  }

  public void testLastOne() throws IOException {
    final PantsProjectCache cache = PantsProjectCacheImpl.getInstance(myFixture.getProject());
    final VirtualFile root = getMainContentRoot();


    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      @Override
      public void run() {
        try {
          PsiTestUtil.addSourceRoot(getModule(), VfsUtil.createDirectoryIfMissing(root, "bar"));
          PsiTestUtil.addSourceRoot(getModule(), VfsUtil.createDirectoryIfMissing(root, "baz"));
          assertTrue(cache.folderContainsSourceRoot(VfsUtil.createDirectoryIfMissing(root, "baz")));
          assertFalse(cache.folderContainsSourceRoot(VfsUtil.createDirectoryIfMissing(root, "ba")));
          assertFalse(cache.folderContainsSourceRoot(VfsUtil.createDirectoryIfMissing(root, "bat")));
        }
        catch (IOException e) {
          fail(e.getMessage());
        }
      }
    });
  }

  public void testFirstOne() throws IOException {
    final PantsProjectCache cache = PantsProjectCacheImpl.getInstance(myFixture.getProject());
    final VirtualFile root = getMainContentRoot();

    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      @Override
      public void run() {
        try {
          PsiTestUtil.addSourceRoot(getModule(), VfsUtil.createDirectoryIfMissing(root, "abc"));
          PsiTestUtil.addSourceRoot(getModule(), VfsUtil.createDirectoryIfMissing(root, "foo/bar"));
          PsiTestUtil.addSourceRoot(getModule(), VfsUtil.createDirectoryIfMissing(root, "foo/baz"));
          assertTrue(cache.folderContainsSourceRoot(VfsUtil.createDirectoryIfMissing(root, "abc")));
          assertTrue(cache.folderContainsSourceRoot(VfsUtil.createDirectoryIfMissing(root, "foo")));
        }
        catch (IOException e) {
          fail(e.getMessage());
        }
      }
    });
  }
}

@@ -990,131 +990,216 @@
     
-ApplicationManager.getApplication().runWriteAction(%0A      new Runnable() %7B%0A        @Override%0A        public void run()
+cleanUpsourceFolders();%0A    PantsProjectCacheImpl.getInstance(getProject()).projectOpened();%0A  %7D%0A%0A  private void cleanUpsourceFolders() %7B%0A    ApplicationManager.getApplication().runWriteAction(%0A      () -%3E
  %7B%0A
-  
     
@@ -1319,26 +1319,24 @@
 ();%0A        
- 
- 
 for (Content
@@ -1405,26 +1405,24 @@
 %7B%0A          
-  
 final Source
@@ -1475,26 +1475,24 @@
 eFolders();%0A
-  
           fo
@@ -1551,18 +1551,16 @@
         
-  
 contentE
@@ -1598,18 +1598,16 @@
 older);%0A
-  
         
@@ -1610,38 +1610,34 @@
       %7D%0A        
-  %7D%0A  
+%7D%0A
         modifiab
@@ -1668,93 +1668,14 @@
     
-  
 %7D%0A    
-  %7D%0A    );%0A    PantsProjectCacheImpl.getInstance(getProject()).projectOpened(
 );%0A 
@@ -1733,24 +1733,52 @@
 Exception %7B%0A
+    cleanUpsourceFolders();%0A
     PantsPro
@@ -1834,28 +1834,16 @@
 osed();%0A
-    try %7B%0A  
     supe
@@ -1860,196 +1860,8 @@
 ();%0A
-    %7D%0A    catch (Exception e) %7B%0A      // TODO: something in the test framework isn't disposed.%0A      if (!e.getMessage().contains(%22hasn't been disposed%22)) %7B%0A        throw e;%0A      %7D%0A    %7D%0A
   %7D%0A
@@ -2328,35 +2328,16 @@
 astOne()
- throws IOException
  %7B%0A    f
@@ -3242,27 +3242,8 @@
 ne()
- throws IOException
  %7B%0A 
@@ -3447,69 +3447,16 @@
 ion(
-new Runnable() %7B%0A      @Override%0A      public void run()
+() -%3E
  %7B%0A
-  
     
@@ -3463,34 +3463,32 @@
   try %7B%0A        
- 
- 
 PsiTestUtil.addS
@@ -3554,26 +3554,24 @@
 t, %22abc%22));%0A
-  
         PsiT
@@ -3649,34 +3649,32 @@
 t, %22foo/bar%22));%0A
-  
         PsiTestU
@@ -3756,34 +3756,32 @@
 baz%22));%0A        
-  
 assertTrue(cache
@@ -3851,26 +3851,24 @@
 , %22abc%22)));%0A
-  
         asse
@@ -3952,38 +3952,34 @@
 %22foo%22)));%0A      
- 
- 
 %7D%0A
-  
       catch (IOE
@@ -3984,34 +3984,32 @@
 OException e) %7B%0A
-  
         fail(e.g
@@ -4018,34 +4018,24 @@
 Message());%0A
-        %7D%0A
       %7D%0A    

Fix resource not disposed error (#412)