// Copyright 2000-2018 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.propertyBased;

import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiSwitchBlock;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.SkipSlowTestLocally;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.testFramework.propertyBased.InvokeIntention;
import com.intellij.testFramework.propertyBased.MadTestingAction;
import com.intellij.testFramework.propertyBased.MadTestingUtil;
import com.intellij.testFramework.propertyBased.StripTestDataMarkup;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jetCheck.Generator;
import org.jetbrains.jetCheck.PropertyChecker;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

@SkipSlowTestLocally
public class Java12SwitchExpressionSanityTest extends LightCodeInsightFixtureTestCase {

  @Override
  protected void tearDown() throws Exception {
    // remove jdk if it was created during highlighting to avoid leaks
    try {
      JavaAwareProjectJdkTableImpl.removeInternalJdkInTests();
    }
    catch (Throwable e) {
      addSuppressedException(e);
    }
    finally {
      super.tearDown();
    }
  }

  @NotNull
  @Override
  protected LightProjectDescriptor getProjectDescriptor() {
    return JAVA_12;
  }

  public void testIntentionsAroundSwitch() {
    MadTestingUtil.enableAllInspections(getProject(), getTestRootDisposable(),
                                        "BoundedWildcard" // IDEA-194460
    );

    Function<PsiFile, Generator<? extends MadTestingAction>> fileActions =
      file -> Generator.sampledFrom(new InvokeIntention(file, new JavaIntentionPolicy()) {
        @Override
        protected int generateDocOffset(@NotNull Environment env, @Nullable String logMessage) {
          Collection<PsiSwitchBlock> children = PsiTreeUtil.findChildrenOfType(getFile(), PsiSwitchBlock.class);
          if (children.isEmpty()) {
            return super.generateDocOffset(env, logMessage);
          }

          List<Generator<Integer>> generators = 
            ContainerUtil.map(children, stmt ->
            Generator.integers(stmt.getTextRange().getStartOffset(),
                               stmt.getTextRange().getEndOffset()).noShrink());
          return env.generateValue(Generator.anyOf(generators), logMessage);
        }
      }, new StripTestDataMarkup(file));

    Supplier<MadTestingAction> fileChooser = MadTestingUtil.actionsOnFileContents(myFixture, PathManager.getHomePath(), f -> {
      try {
        return f.getName().endsWith(".java") && FileUtil.loadFile(f).contains(" switch");
      }
      catch (IOException e) {
        return false;
      }
    }, fileActions);
    PropertyChecker.checkScenarios(fileChooser);
  }

}

@@ -337,23 +337,132 @@
 api.
-util.io.FileUti
+roots.LanguageLevelProjectExtension;%0Aimport com.intellij.openapi.util.io.FileUtil;%0Aimport com.intellij.pom.java.LanguageLeve
 l;%0Ai
@@ -816,222 +816,9 @@
 sed.
-InvokeIntention;%0Aimport com.intellij.testFramework.propertyBased.MadTestingAction;%0Aimport com.intellij.testFramework.propertyBased.MadTestingUtil;%0Aimport com.intellij.testFramework.propertyBased.StripTestDataMarkup
+*
 ;%0Aim
@@ -1626,16 +1626,204 @@
  %7D%0A  %7D%0A%0A
+  @Override%0A  protected void setUp() throws Exception %7B%0A    super.setUp();%0A    LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_12_PREVIEW);%0A  %7D%0A%0A
   @NotNu
@@ -2793,24 +2793,24 @@
 rtOffset(),%0A
-
             
@@ -2960,24 +2960,1190 @@
 ;%0A        %7D%0A
+      %7D, new InvokeIntention(file, new IntentionPolicy() %7B%0A                                      @Override%0A                                      protected boolean shouldSkipIntention(@NotNull String actionText) %7B%0A                                        return !%22Replace with 'switch' expression%22.equals(actionText) && !%22Replace with enhanced 'switch' statement%22.equals(actionText);%0A                                      %7D%0A                                    %7D) %7B%0A        @Override%0A        protected int generateDocOffset(@NotNull Environment env, @Nullable String logMessage) %7B%0A          Collection%3CPsiSwitchBlock%3E children = PsiTreeUtil.findChildrenOfType(getFile(), PsiSwitchBlock.class);%0A          if (children.isEmpty()) %7B%0A            return super.generateDocOffset(env, logMessage);%0A          %7D%0A%0A          List%3CGenerator%3CInteger%3E%3E generators = %0A            ContainerUtil.map(children, stmt -%3E%0A            Generator.integers(stmt.getFirstChild().getTextRange().getStartOffset(),%0A                               stmt.getFirstChild().getTextRange().getEndOffset()).noShrink());%0A          return env.generateValue(Generator.anyOf(generators), logMessage);%0A        %7D%0A
       %7D, new

switch expression dedicated property test