package com.jetbrains.lang.dart.ide.runner.client;
import com.intellij.ide.browsers.BrowserFamily;
import com.intellij.ide.browsers.BrowserSpecificSettings;
import com.intellij.ide.browsers.WebBrowser;
import com.intellij.ide.browsers.WebBrowserManager;
import com.intellij.ide.browsers.chrome.ChromeSettings;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.lang.dart.DartBundle;
import com.jetbrains.lang.dart.sdk.DartSdkUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Map;
import java.util.UUID;
public class DartiumUtil {
private static final String DART_FLAGS_ENV_VAR = "DART_FLAGS";
public static final String CHECKED_MODE_OPTION = "--checked";
private static final String ENABLE_ASYNC_OPTION = "--enable-async";
private static final UUID DARTIUM_ID = UUID.fromString("BFEE1B69-A97D-4338-8BA4-25170ADCBAA6");
private static final String DARTIUM_NAME = "Dartium";
@Nullable
public static WebBrowser getDartiumBrowser() {
WebBrowser browser = WebBrowserManager.getInstance().findBrowserById(DARTIUM_ID.toString());
if (browser == null) browser = WebBrowserManager.getInstance().findBrowserById(DARTIUM_NAME);
return browser != null && browser.getFamily() == BrowserFamily.CHROME ? browser : null;
}
@Nullable
public static String getDartiumPathForSdk(final @NotNull String sdkHomePath) {
final File sdkDir = new File(sdkHomePath);
if (!sdkDir.isDirectory()) return null;
final File dartDir = sdkDir.getParentFile();
final String relativePath = SystemInfo.isMac ? "chromium/Chromium.app"
: SystemInfo.isWindows ? "chromium/chrome.exe"
: "chromium/chrome";
final File dartiumPath = new File(dartDir, relativePath);
return dartiumPath.exists() ? FileUtil.toSystemIndependentName(dartiumPath.getPath()) : null;
}
@NotNull
public static WebBrowser ensureDartiumBrowserConfigured(final @Nullable String dartiumPath) {
final WebBrowser browser = getDartiumBrowser();
if (browser == null) {
return WebBrowserManager.getInstance().addBrowser(DARTIUM_ID, BrowserFamily.CHROME, DARTIUM_NAME, dartiumPath, true,
BrowserFamily.CHROME.createBrowserSpecificSettings());
}
else {
if (!Comparing.equal(dartiumPath, browser.getPath())) {
WebBrowserManager.getInstance().setBrowserPath(browser, dartiumPath, true);
}
return browser;
}
}
@Nullable
public static String getErrorMessageIfWrongDartiumPath(final @NotNull String dartiumPath) {
// Don't warn if Dartium is not configured.
if (dartiumPath.isEmpty()) return null;
final File file = new File(dartiumPath);
if (SystemInfo.isMac && !file.isDirectory() || !SystemInfo.isMac && !file.isFile()) {
return DartBundle.message("warning.invalid.dartium.path");
}
return null;
}
public static void applyDartiumSettings(final @NotNull String dartiumPathFromUI, final @NotNull ChromeSettings dartiumSettingsFromUI) {
final WebBrowser dartiumInitial = getDartiumBrowser();
final String dartiumPathInitial = dartiumInitial == null ? null : dartiumInitial.getPath();
if (!dartiumPathFromUI.isEmpty() && new File(dartiumPathFromUI).exists() && !dartiumPathFromUI.equals(dartiumPathInitial)) {
DartSdkUtil.updateKnownDartiumPaths(dartiumPathInitial, dartiumPathFromUI);
final WebBrowser browser = ensureDartiumBrowserConfigured(dartiumPathFromUI);
if (!dartiumSettingsFromUI.equals(browser.getSpecificSettings())) {
WebBrowserManager.getInstance().setBrowserSpecificSettings(browser, dartiumSettingsFromUI);
}
return;
}
if (dartiumInitial != null && !dartiumSettingsFromUI.equals(dartiumInitial.getSpecificSettings())) {
WebBrowserManager.getInstance().setBrowserSpecificSettings(dartiumInitial, dartiumSettingsFromUI);
}
}
public static boolean isCheckedMode(@NotNull final Map<String, String> envVars) {
return hasDartFlag(envVars, CHECKED_MODE_OPTION);
}
private static boolean hasDartFlag(final Map<String, String> envVars, final String dartFlag) {
final String dartFlags = envVars.get(DART_FLAGS_ENV_VAR);
return dartFlags != null && (dartFlags.trim().equals(dartFlag) ||
dartFlags.startsWith(dartFlag + " ") ||
dartFlags.endsWith(" " + dartFlag) ||
dartFlags.contains(" " + dartFlag + " "));
}
public static void setCheckedMode(@NotNull final Map<String, String> envVars, final boolean checkedMode) {
setDartFlagState(envVars, CHECKED_MODE_OPTION, checkedMode);
}
private static void setDartFlagState(final Map<String, String> envVars, final String dartFlag, final boolean flagState) {
final boolean oldFlagState = hasDartFlag(envVars, dartFlag);
if (oldFlagState == flagState) return;
final String dartFlags = envVars.get(DART_FLAGS_ENV_VAR);
if (flagState) {
if (dartFlags == null) {
envVars.put(DART_FLAGS_ENV_VAR, dartFlag);
}
else {
envVars.put(DART_FLAGS_ENV_VAR, dartFlags + " " + dartFlag);
}
}
else {
String newFlags = dartFlags;
if (newFlags.trim().equals(dartFlag)) {
newFlags = "";
}
newFlags = StringUtil.trimStart(newFlags, dartFlag + " ");
newFlags = StringUtil.trimEnd(newFlags, " " + dartFlag);
final int index = newFlags.indexOf(" " + dartFlag + " ");
if (index != -1) {
// keep one space between parts
newFlags = newFlags.substring(0, index) + newFlags.substring(index + dartFlag.length() + 1);
}
if (StringUtil.isEmptyOrSpaces(newFlags)) {
envVars.remove(DART_FLAGS_ENV_VAR);
}
else {
envVars.put(DART_FLAGS_ENV_VAR, newFlags);
}
}
}
public static void resetDartiumFlags() {
final WebBrowser dartium = getDartiumBrowser();
final BrowserSpecificSettings browserSpecificSettings = dartium == null ? null : dartium.getSpecificSettings();
if (!(browserSpecificSettings instanceof ChromeSettings)) return;
final Map<String, String> envVars = browserSpecificSettings.getEnvironmentVariables();
setDartFlagState(envVars, ENABLE_ASYNC_OPTION, false);
setDartFlagState(envVars, CHECKED_MODE_OPTION, true);
}
}