package jetbrains.mps.refactoring.test.test;

/*Generated by MPS */

import org.junit.jupiter.api.extension.ExtendWith;
import jetbrains.mps.baseLanguage.unitTest.runtime.EnvironmentAwareExtension;
import jetbrains.mps.testbench.EnvironmentAwareTestCase;
import jetbrains.mps.logging.Logger;
import jetbrains.mps.project.Project;
import org.junit.jupiter.api.BeforeEach;
import jetbrains.mps.util.NameUtil;
import java.io.File;
import java.nio.file.Files;
import jetbrains.mps.util.FileUtil;
import org.junit.jupiter.api.AfterEach;
import java.util.List;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.make.MakeSession;
import jetbrains.mps.messages.LogHandler;
import jetbrains.mps.messages.MessageKind;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.make.resources.IResource;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.ide.make.actions.MakeActionParameters;
import java.util.concurrent.Future;
import jetbrains.mps.make.script.IResult;
import jetbrains.mps.tool.builder.make.BuildMakeService;
import org.junit.Assert;
import java.util.concurrent.ExecutionException;

@ExtendWith(value = EnvironmentAwareExtension.class)
public abstract class AbstractRefactoringTest extends EnvironmentAwareTestCase {
  private static final Logger LOG = Logger.getLogger(AbstractRefactoringTest.class);
  protected Project project;
  private String projectTempDir;
  private String projectSourcePath;
  public AbstractRefactoringTest(String path) {
    projectSourcePath = path;
  }

  @BeforeEach
  protected void openProject() throws Exception {
    String dirPrefix = NameUtil.toConstantName(NameUtil.toValidIdentifier(getClass().getSimpleName()));
    File tempDir = Files.createTempDirectory(dirPrefix).toFile();
    projectTempDir = tempDir.getCanonicalPath();
    FileUtil.copyDir(new File(projectSourcePath), tempDir);
    project = myEnvironment.openProject(tempDir);
  }

  @AfterEach
  protected void closeProject() throws Exception {
    myEnvironment.closeProject(project);
    com.intellij.openapi.util.io.FileUtil.delete(new File(projectTempDir));
  }

  public void doMake(final List<SModule> modules, final boolean cleanMake) {
    if (LOG.isInfoLevel()) {
      LOG.info("Making modules: " + ListSequence.fromList(modules).toList());
    }
    MakeSession session = new MakeSession(project, new LogHandler(Logger.getLogger(AbstractRefactoringTest.class)).restrict(MessageKind.ERROR), true);
    final Wrappers._T<List<? extends IResource>> inputRes = new Wrappers._T<List<? extends IResource>>(null);
    project.getRepository().getModelAccess().runReadAction(() -> inputRes.value = Sequence.fromIterable(new MakeActionParameters(project).cleanMake(cleanMake).modules(modules).collectInput()).toList());
    // FIXME install proper IMakeService in MpsTestsSuite (likely, TestMakeService, to avoid 
    // superfluous tool.builder dependency here)
    Future<IResult> res = new BuildMakeService().make(session, inputRes.value);
    try {
      Assert.assertTrue("Make was not successful", res.get().isSucessful());
    } catch (InterruptedException e) {
      Assert.fail(e.toString());
    } catch (ExecutionException e) {
      Assert.fail(e.toString());
    }
    if (LOG.isInfoLevel()) {
      LOG.info("Make finished");
    }
  }

}
