package org.jetbrains.plugins.ruby.motion.bridgesupport;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.ruby.motion.RubyMotionUtil;
import org.jetbrains.plugins.ruby.utils.VirtualFileUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Dennis.Ushakov
*/
public class BridgeSupportLoader {
private final Map<String, List<FrameworkInfo>> myFrameworks = new HashMap<>();
public static BridgeSupportLoader getInstance() {
return ServiceManager.getService(BridgeSupportLoader.class);
}
@Nullable
public Framework getFramework(String version, String name) {
final FrameworkInfo frameworkInfo = getFrameworkInfo(version, name);
return frameworkInfo != null ? frameworkInfo.getFramework() : null;
}
@Nullable
private FrameworkInfo getFrameworkInfo(String version, String name) {
ensureFrameworksLoaded();
final List<FrameworkInfo> frameworkInfos = myFrameworks.get(version);
if (frameworkInfos == null) return null;
for (FrameworkInfo frameworkInfo : frameworkInfos) {
if (frameworkInfo.getName().equals(name)) {
return frameworkInfo;
}
}
return null;
}
private synchronized void ensureFrameworksLoaded() {
if (!myFrameworks.isEmpty()) {
return;
}
VirtualFile rubyMotion = VirtualFileUtil.findFileBy(RubyMotionUtil.getInstance().getRubyMotionPath() + "/data/ios/");
rubyMotion = rubyMotion == null ? VirtualFileUtil.findFileBy(RubyMotionUtil.getInstance().getRubyMotionPath() + "/data/") : rubyMotion;
loadSdks(rubyMotion);
if (rubyMotion == null || !"ios".equals(rubyMotion.getName())) {
return;
}
rubyMotion = VirtualFileUtil.findFileBy(RubyMotionUtil.getInstance().getRubyMotionPath() + "/data/android/");
loadSdks(rubyMotion);
rubyMotion = VirtualFileUtil.findFileBy(RubyMotionUtil.getInstance().getRubyMotionPath() + "/data/osx/");
loadSdks(rubyMotion);
}
private void loadSdks(VirtualFile rubyMotion) {
if (rubyMotion == null) {
return;
}
for (VirtualFile file : rubyMotion.getChildren()) {
if (file.isDirectory()) {
final VirtualFile bridgeSupport = file.findChild("BridgeSupport");
if (bridgeSupport == null) continue;
ensureFrameworkLoaded(bridgeSupport);
}
}
}
private void ensureFrameworkLoaded(final VirtualFile bridgeSupport) {
String version = bridgeSupport.getParent().getName();
List<FrameworkInfo> frameworkInfos = ContainerUtil.newArrayList();
for (VirtualFile file : bridgeSupport.getChildren()) {
final String name = file.getNameWithoutExtension();
if (RubyMotionUtil.getInstance().isIgnoredFrameworkName(name)) continue;
if ("bridgesupport".equals(file.getExtension()) && file.getLength() > 0) {
boolean isOSX = "osx".equals(file.getParent().getParent().getParent().getName());
frameworkInfos.add(new FrameworkInfo(name, version, isOSX, file.getPath()));
}
}
myFrameworks.put(version, frameworkInfos);
}
public boolean isIdSelector(String name, String sdkVersion, String frameworkName) {
final FrameworkInfo info = getFrameworkInfo(sdkVersion, frameworkName);
if (info == null) return false;
Set<String> selectors = info.getIdSelectorNames();
return selectors != null && selectors.contains(name);
}
public boolean isSelector(String name, String sdkVersion, String frameworkName) {
final FrameworkInfo info = getFrameworkInfo(sdkVersion, frameworkName);
if (info == null) return false;
Set<String> selectors = info.getSelectorNames();
return selectors != null && selectors.contains(name);
}
public void processFrameworks(Consumer<Framework> consumer) {
ensureFrameworksLoaded();
for (List<FrameworkInfo> frameworkInfos : myFrameworks.values()) {
for (FrameworkInfo frameworkInfo : frameworkInfos) {
Framework framework = frameworkInfo.getFramework();
if (framework != null) {
consumer.consume(framework);
}
}
}
}
}