package it.paspiz85.nanobot.platform;
import it.paspiz85.nanobot.platform.mac.BlueStacksMacPlatform;
import it.paspiz85.nanobot.platform.win.BlueStacksWinPlatform;
import it.paspiz85.nanobot.util.Utils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Factory for {@link Platform}.
*
* @author paspiz85
*
*/
public final class PlatformResolver implements Supplier<Platform> {
private static final String IS_SUPPORTED_METHOD = "isSupported";
private static final String INSTANCE_METHOD = "instance";
public static PlatformResolver instance() {
return Utils.singleton(PlatformResolver.class, () -> new PlatformResolver());
}
private Platform platform;
private final List<Class<? extends Platform>> platforms = new ArrayList<>();
private Class<? extends Platform> preferredPlatform;
protected final Logger logger = Logger.getLogger(getClass().getName());
private PlatformResolver() {
platforms.add(BlueStacksWinPlatform.class);
platforms.add(BlueStacksMacPlatform.class);
}
@Override
public Platform get() {
if (platform == null) {
Class<? extends Platform> platformClass = preferredPlatform;
if (platformClass == null) {
final List<Class<? extends Platform>> supportedPlatforms = getSupportedPlatforms();
if (!supportedPlatforms.isEmpty()) {
platformClass = supportedPlatforms.get(0);
}
}
if (platformClass == null) {
platformClass = UnsupportedPlatform.class;
}
platform = getInstance(platformClass);
}
return platform;
}
private Platform getInstance(final Class<? extends Platform> platformClass) {
try {
return (Platform) platformClass.getMethod(INSTANCE_METHOD).invoke(null);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException e) {
throw new IllegalStateException("unable to initialize platform instance", e);
}
}
public List<Class<? extends Platform>> getPlatforms() {
return platforms;
}
public Class<? extends Platform> getPreferredPlatform() {
return preferredPlatform;
}
public List<Class<? extends Platform>> getSupportedPlatforms() {
final List<Class<? extends Platform>> supportedPlatforms = new ArrayList<>();
for (final Class<? extends Platform> platform : platforms) {
try {
platform.getMethod(INSTANCE_METHOD);
if ((boolean) platform.getMethod(IS_SUPPORTED_METHOD).invoke(null)) {
supportedPlatforms.add(platform);
}
} catch (final Exception e) {
logger.log(Level.SEVERE, "Platform not supperted: " + platform.getName(), e);
}
}
return supportedPlatforms;
}
public void setPreferredPlatform(final Class<? extends Platform> preferredPlatform) {
this.preferredPlatform = preferredPlatform;
this.platform = null;
}
}