package com.jetbrains.lang.dart.sdk;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.lang.dart.DartProjectComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DartSdk {
public static final String DART_SDK_LIB_NAME = "Dart SDK";
private static final String UNKNOWN_VERSION = "unknown";
private static final Key<CachedValue<DartSdk>> CACHED_DART_SDK_KEY = Key.create("CACHED_DART_SDK_KEY");
private final @NotNull String myHomePath;
private final @NotNull String myVersion;
private DartSdk(@NotNull final String homePath, @NotNull final String version) {
myHomePath = homePath;
myVersion = version;
}
@NotNull
public String getHomePath() {
return myHomePath;
}
/**
* @return presentable version with revision, like "1.9.1_r44672" or "1.9.0-dev.10.9_r44532" or "1.10.0-edge.44829"
*/
@NotNull
public String getVersion() {
return myVersion;
}
@Nullable
public static DartSdk getDartSdk(@NotNull final Project project) {
CachedValue<DartSdk> cachedValue = project.getUserData(CACHED_DART_SDK_KEY);
if (cachedValue == null) {
cachedValue = CachedValuesManager.getManager(project).createCachedValue(() -> {
final DartSdk sdk = findDartSdkAmongLibraries(ProjectLibraryTable.getInstance(project).getLibraries());
if (sdk == null) {
return new CachedValueProvider.Result<>(null, DartProjectComponent.getProjectRootsModificationTracker(project));
}
List<Object> dependencies = new ArrayList<>(3);
dependencies.add(DartProjectComponent.getProjectRootsModificationTracker(project));
ContainerUtil.addIfNotNull(dependencies, LocalFileSystem.getInstance().findFileByPath(sdk.getHomePath() + "/version"));
ContainerUtil.addIfNotNull(dependencies, LocalFileSystem.getInstance().findFileByPath(sdk.getHomePath() + "/lib/core/core.dart"));
return new CachedValueProvider.Result<>(sdk, ArrayUtil.toObjectArray(dependencies));
}, false);
project.putUserData(CACHED_DART_SDK_KEY, cachedValue);
}
return cachedValue.getValue();
}
@Nullable
private static DartSdk findDartSdkAmongLibraries(final Library[] libs) {
for (final Library library : libs) {
if (DART_SDK_LIB_NAME.equals(library.getName())) {
return getSdkByLibrary(library);
}
}
return null;
}
@Nullable
public static DartSdk getSdkByLibrary(@NotNull final Library library) {
final VirtualFile[] roots = library.getFiles(OrderRootType.CLASSES);
final VirtualFile dartCoreRoot = DartSdkLibraryPresentationProvider.findDartCoreRoot(Arrays.asList(roots));
if (dartCoreRoot != null) {
final String homePath = dartCoreRoot.getParent().getParent().getPath();
final String version = StringUtil.notNullize(DartSdkUtil.getSdkVersion(homePath), UNKNOWN_VERSION);
return new DartSdk(homePath, version);
}
return null;
}
}