package org.elixir_lang.mix.importWizard;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Platform;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.*;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectImportBuilder;
import com.intellij.projectImport.ProjectImportWizardStep;
import org.elixir_lang.jps.model.JpsElixirSdkType;
import org.elixir_lang.mix.settings.MixConfigurationForm;
import org.elixir_lang.sdk.ElixirSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
/**
* Created by zyuyou on 15/7/1.
* https://github.com/ignatov/intellij-erlang/blob/master/src/org/intellij/erlang/rebar/importWizard/RebarProjectRootStep.java
*/
public class MixProjectRootStep extends ProjectImportWizardStep {
private static final Logger LOG = Logger.getInstance(MixProjectImportBuilder.class);
private JPanel myPanel;
private TextFieldWithBrowseButton myProjectRootComponent;
private JCheckBox myGetDepsCheckbox;
private MixConfigurationForm myMixConfigurationForm;
private static final boolean ourEnabled = !SystemInfo.isWindows;
public MixProjectRootStep(WizardContext context) {
super(context);
String projectFileDirectory = context.getProjectFileDirectory();
myProjectRootComponent.addBrowseFolderListener("Select mix.exs of a mix project to import", "", null,
FileChooserDescriptorFactory.createSingleFolderDescriptor());
myProjectRootComponent.setText(projectFileDirectory); // provide project path
myGetDepsCheckbox.setVisible(ourEnabled);
myMixConfigurationForm.setPath(getMixPath(projectFileDirectory));
}
@Override
public JComponent getComponent() {
myMixConfigurationForm.createComponent();
return myPanel;
}
@Override
public void updateDataModel() {
String projectRoot = myProjectRootComponent.getText();
if(!projectRoot.isEmpty()){
suggestProjectNameAndPath(null, projectRoot);
}
}
@Override
public boolean validate() throws ConfigurationException {
String projectRootPath = myProjectRootComponent.getText();
if(StringUtil.isEmpty(projectRootPath)){
return false;
}
VirtualFile projectRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(projectRootPath);
if(projectRoot == null){
return false;
}
if(myGetDepsCheckbox.isSelected() && !ApplicationManager.getApplication().isUnitTestMode()){
if(!myMixConfigurationForm.isPathValid()){
return false;
}
fetchDependencies(projectRoot, myMixConfigurationForm.getPath());
}
MixProjectImportBuilder builder = getBuilder();
builder.setMixPath(myMixConfigurationForm.getPath());
builder.setIsImportingProject(getWizardContext().isCreatingNewProject());
return builder.setProjectRoot(projectRoot);
}
@Override
@NotNull
public JComponent getPreferredFocusedComponent() {
return myProjectRootComponent.getTextField();
}
@Override
@NotNull
protected MixProjectImportBuilder getBuilder() {
return (MixProjectImportBuilder) super.getBuilder();
}
/**
* private methods
* */
@NotNull
private static String getMixPath(@Nullable String directory){
if(directory != null){
File mix = new File(directory, "mix");
if(mix.exists() && mix.canExecute()){
return mix.getPath();
}
}
String output = "";
GeneralCommandLine generalCommandLine = null;
if (SystemInfo.isWindows) {
generalCommandLine = new GeneralCommandLine("where");
generalCommandLine.addParameter("mix.bat");
} else if (SystemInfo.isMac || SystemInfo.isLinux || SystemInfo.isUnix) {
generalCommandLine = new GeneralCommandLine("which");
generalCommandLine.addParameter("mix");
}
if (generalCommandLine != null) {
try {
output = ScriptRunnerUtil.getProcessOutput(generalCommandLine);
} catch (Exception ignored) {
LOG.warn(ignored);
}
}
return output.trim();
}
private static void fetchDependencies(@NotNull final VirtualFile projectRoot, @NotNull final String mixPath){
final Project project = ProjectImportBuilder.getCurrentProject();
String sdkPath = project != null ? ElixirSdkType.getSdkPath(project) : null;
final String elixirPath = sdkPath != null ?
JpsElixirSdkType.getScriptInterpreterExecutable(sdkPath).getAbsolutePath() :
JpsElixirSdkType.getExecutableFileName(JpsElixirSdkType.SCRIPT_INTERPRETER);
ProgressManager.getInstance().run(new Task.Modal(project, "Fetching dependencies", true){
@Override
public void run(@NotNull final ProgressIndicator indicator) {
indicator.setIndeterminate(true);
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.withWorkDirectory(projectRoot.getCanonicalPath());
commandLine.setExePath(elixirPath);
commandLine.addParameter(mixPath);
commandLine.addParameter("deps.get");
try{
OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), commandLine.getPreparedCommandLine(Platform.current()));
handler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
String text = event.getText();
indicator.setText2(text);
}
});
ProcessTerminatedListener.attach(handler);
handler.startNotify();
handler.waitFor();
indicator.setText2("Refreshing");
}catch (ExecutionException e){
LOG.warn(e);
}
}
});
}
}