package com.thoughtworks.gauge.extract;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogBuilder;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.thoughtworks.gauge.annotator.FileManager;
import com.thoughtworks.gauge.language.psi.ConceptTable;
import com.thoughtworks.gauge.language.psi.SpecPsiImplUtil;
import com.thoughtworks.gauge.language.psi.SpecTable;
import com.thoughtworks.gauge.language.psi.impl.ConceptStepImpl;
import com.thoughtworks.gauge.language.psi.impl.SpecStepImpl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ExtractConceptInfoCollector {
public static final String CREATE_NEW_FILE = "Create New File(Enter info in the below field)";
private final Editor editor;
private final Map<String, String> tableMap;
private final List<PsiElement> steps;
private Project project;
public ExtractConceptInfoCollector(Editor editor, Map<String, String> tableMap, List<PsiElement> steps, Project project) {
this.editor = editor;
this.tableMap = tableMap;
this.steps = steps;
this.project = project;
}
public ExtractConceptInfo getAllInfo() {
String steps = getFormattedSteps();
List<String> args = getArgs(steps);
final ExtractConceptDialog form = new ExtractConceptDialog(this.editor.getProject(), args, FileManager.getDirNamesUnderSpecs(project));
showDialog(steps, form);
if (form.getInfo().cancelled)
return form.getInfo();
String fileName = form.getInfo().fileName;
if (!fileName.startsWith(File.separator)) fileName = File.separator + fileName;
return new ExtractConceptInfo(form.getInfo().conceptName, project.getBasePath() + fileName, form.getInfo().cancelled);
}
private List<String> getArgs(String steps) {
List<String> args = new ArrayList<>();
for (String step : steps.split("\n"))
args.addAll(SpecPsiImplUtil.getStepValueFor(this.steps.get(0), step, false).getParameters()
.stream()
.map(p -> getNameWithParamChar(StringUtil.unescapeStringCharacters(step), p))
.collect(Collectors.toList()));
return args;
}
private String getNameWithParamChar(String step, String p) {
String arg = StringUtil.escapeStringCharacters(p);
return step.charAt(step.indexOf(p) - 1) + arg + step.charAt(step.indexOf(p) + p.length());
}
private void showDialog(String steps, ExtractConceptDialog form) {
final DialogBuilder builder = new DialogBuilder(editor.getProject());
form.setData(steps, getConceptFileNames(), builder);
builder.setCenterPanel(form.getRootPane());
builder.setTitle("Extract Concept");
builder.removeAllActions();
builder.show();
}
private List<String> getConceptFileNames() {
List<PsiFile> files = FileManager.getAllConceptFiles(editor.getProject());
List<String> names = new ArrayList<>();
names.add(CREATE_NEW_FILE);
files.forEach((file) -> names.add(file.getVirtualFile().getPath().replace(project.getBasePath() + File.separator, "")));
return names;
}
private String getFormattedSteps() {
StringBuilder builder = new StringBuilder();
for (PsiElement step : steps)
builder = step.getClass().equals(SpecStepImpl.class) ? formatStep(builder, (SpecStepImpl) step) : formatStep(builder, (ConceptStepImpl) step);
return builder.toString();
}
private StringBuilder formatStep(StringBuilder builder, SpecStepImpl step) {
SpecTable table = step.getInlineTable();
if (table != null) {
builder.append(step.getText().trim().replace(table.getText().trim(), "").trim())
.append(" <").append(tableMap.get(table.getText().trim())).append(">").append("\n");
return builder;
}
return builder.append(step.getText().trim()).append("\n");
}
private StringBuilder formatStep(StringBuilder builder, ConceptStepImpl step) {
ConceptTable table = step.getTable();
if (table != null) {
builder.append(step.getText().trim().replace(table.getText().trim(), "").trim())
.append(" <").append(tableMap.get(table.getText().trim())).append(">").append("\n");
return builder;
}
return builder.append(step.getText().trim()).append("\n");
}
}