package name.admitriev.jhelper.components;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.text.StringTokenizer;
import com.jetbrains.cidr.lang.psi.OCFile;
import name.admitriev.jhelper.IDEUtils;
import name.admitriev.jhelper.network.SimpleHttpServer;
import name.admitriev.jhelper.task.TaskData;
import name.admitriev.jhelper.task.TaskUtils;
import name.admitriev.jhelper.ui.Notificator;
import name.admitriev.jhelper.ui.UIUtils;
import net.egork.chelper.parser.AtCoderParser;
import net.egork.chelper.parser.BayanParser;
import net.egork.chelper.parser.CSAcademyParser;
import net.egork.chelper.parser.CodeChefParser;
import net.egork.chelper.parser.CodeforcesParser;
import net.egork.chelper.parser.FacebookParser;
import net.egork.chelper.parser.GCJParser;
import net.egork.chelper.parser.HackerEarthParser;
import net.egork.chelper.parser.HackerRankParser;
import net.egork.chelper.parser.KattisParser;
import net.egork.chelper.parser.Parser;
import net.egork.chelper.parser.UsacoParser;
import net.egork.chelper.parser.YandexParser;
import net.egork.chelper.task.Task;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A Component to monitor request from CHelper Chrome Extension and parse them to Tasks
*/
public class ChromeParser extends AbstractProjectComponent {
private static final int PORT = 4243;
private static final Map<String, Parser> PARSERS;
static {
Map<String, Parser> taskParsers = new HashMap<>();
taskParsers.put("yandex", new YandexParser());
taskParsers.put("codeforces", new CodeforcesParser());
taskParsers.put("hackerrank", new HackerRankParser());
taskParsers.put("facebook", new FacebookParser());
taskParsers.put("usaco", new UsacoParser());
taskParsers.put("gcj", new GCJParser());
taskParsers.put("bayan", new BayanParser());
taskParsers.put("kattis", new KattisParser());
taskParsers.put("codechef", new CodeChefParser());
taskParsers.put("hackerearth", new HackerEarthParser());
taskParsers.put("atcoder", new AtCoderParser());
taskParsers.put("csacademy", new CSAcademyParser());
PARSERS = Collections.unmodifiableMap(taskParsers);
}
private SimpleHttpServer server = null;
public ChromeParser(Project project) {
super(project);
}
@Override
public void projectOpened() {
try {
Configurator configurator = myProject.getComponent(Configurator.class);
Configurator.State configuration = configurator.getState();
String path = configuration.getTasksDirectory();
server = new SimpleHttpServer(
PORT,
request -> {
StringTokenizer st = new StringTokenizer(request);
String type = st.nextToken();
Parser parser = PARSERS.get(type);
if (parser == null) {
Notificator.showNotification(
"Unknown parser",
"Parser " + type + " unknown, request ignored",
NotificationType.INFORMATION
);
return;
}
String page = request.substring(st.getCurrentPosition());
Collection<Task> tasks = parser.parseTaskFromHTML(page);
if (tasks.isEmpty()) {
Notificator.showNotification(
"Couldn't parse any task",
"Maybe format changed?",
NotificationType.WARNING
);
}
for (Task rawTask : tasks) {
TaskData task = new TaskData(
rawTask.name,
rawTask.taskClass,
String.format("%s/%s.cpp", path, rawTask.taskClass),
rawTask.input,
rawTask.output,
rawTask.testType,
rawTask.tests
);
PsiElement generatedFile = TaskUtils.saveNewTask(task, myProject);
UIUtils.openMethodInEditor(myProject, (OCFile) generatedFile, "solve");
}
IDEUtils.reloadProject(myProject);
}
);
new Thread(server, "ChromeParserThread").start();
}
catch (IOException ignored) {
Notificator.showNotification(
"Could not create serverSocket for Chrome parser",
"Probably another CHelper or JHelper project is running?",
NotificationType.ERROR
);
}
}
@Override
public void projectClosed() {
if (server != null) {
server.stop();
}
}
}