// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.openapi.roots.impl;

import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.VfsTestUtil;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@PlatformTestCase.WrapInCommand
public class DirectoryIndexRestoreTest extends IdeaTestCase {
  private VirtualFile myTempVFile;
  private String myTestDirPath;

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    LocalFileSystem fs = LocalFileSystem.getInstance();
    File temp = createTempDirectory();
    myTempVFile = fs.refreshAndFindFileByIoFile(temp);
    assertNotNull(myTempVFile);
    File root = new File(temp, "top/d1/d2/root");
    assertTrue(root.mkdirs());
    VirtualFile rootVFile = fs.refreshAndFindFileByIoFile(root);
    assertNotNull(rootVFile);

    VirtualFile moduleDir = createChildDirectory(rootVFile, "module");
    VirtualFile srcDir = createChildDirectory(moduleDir, "src");
    VirtualFile testDir = createChildDirectory(srcDir, "pkg");
    ModuleRootModificationUtil.setModuleSdk(myModule, null);
    PsiTestUtil.addContentRoot(myModule, moduleDir);
    PsiTestUtil.addSourceRoot(myModule, srcDir);

    myTestDirPath = testDir.getPath();

    // to not interfere with previous test firing vfs events
    VirtualFileManager.getInstance().syncRefresh();
  }

  public void testDeepDeleteAndRecreate() throws IOException {
    AtomicInteger counter = new AtomicInteger(0);
    ContentIterator iterator = file -> {
      boolean found = file.getPath().equals(myTestDirPath);
      if (found) counter.incrementAndGet();
      return !found;
    };
    File topFile = new File(myTempVFile.getPath(), "top");
    assertTrue(topFile.exists());
    File bakFile = new File(myTempVFile.getPath(), "top.bak");
    assertFalse(bakFile.exists());
    String topPath = FileUtil.toSystemIndependentName(topFile.getPath());

    ProjectRootManager.getInstance(myProject).getFileIndex().iterateContent(iterator);
    assertEquals(1, counter.get());

    FileUtil.rename(topFile, bakFile);
    List<String> events1 = VfsTestUtil.print(VfsTestUtil.getEvents(() -> myTempVFile.refresh(false, true)));
    String bakPath = FileUtil.toSystemIndependentName(bakFile.getPath());
    assertSameElements(events1, Arrays.asList("C : " + bakPath, "D : " + topPath));
    ProjectRootManager.getInstance(myProject).getFileIndex().iterateContent(iterator);
    assertEquals(1, counter.get());

    FileUtil.rename(bakFile, topFile);
    List<String> events2 = VfsTestUtil.print(VfsTestUtil.getEvents(() -> myTempVFile.refresh(false, true)));
    assertSameElements(events2, Arrays.asList("D : " + bakPath, "C : " + topPath));
    ProjectRootManager.getInstance(myProject).getFileIndex().iterateContent(iterator);
    assertEquals(2, counter.get());
  }
}
@@ -788,33 +788,8 @@
 on;%0A
-import java.util.Arrays;%0A
 impo
@@ -2456,82 +2456,8 @@
 ());
-%0A    String topPath = FileUtil.toSystemIndependentName(topFile.getPath());
 %0A%0A  
@@ -2730,166 +2730,8 @@
 ));%0A
-    String bakPath = FileUtil.toSystemIndependentName(bakFile.getPath());%0A    assertSameElements(events1, Arrays.asList(%22C : %22 + bakPath, %22D : %22 + topPath));%0A
     
@@ -2822,32 +2822,61 @@
    assertEquals(
+%22Events recorded: %22+events1, 
 1, counter.get()
@@ -3031,92 +3031,8 @@
 ));%0A
-    assertSameElements(events2, Arrays.asList(%22D : %22 + bakPath, %22C : %22 + topPath));%0A
     
@@ -3106,32 +3106,32 @@
 tent(iterator);%0A
-
     assertEquals
@@ -3131,16 +3131,45 @@
 tEquals(
+%22Events recorded: %22+events2, 
 2, count

fix test: do not check exact events sequence since they are irrelevant to the test (for IDEA-CR-43262)