package org.ultramine.bootstrap.task;
import org.apache.commons.io.FileUtils;
import org.ultramine.bootstrap.Constants;
import org.ultramine.bootstrap.util.I18n;
import org.ultramine.bootstrap.UMCoreVersionsRetriever;
import org.ultramine.bootstrap.util.UmSslUtil;
import org.ultramine.bootstrap.deps.IRepository;
import org.ultramine.bootstrap.maven.MavenDependency;
import org.ultramine.bootstrap.maven.MavenLocalRepository;
import org.ultramine.bootstrap.maven.MavenRemoteRepository;
import org.ultramine.bootstrap.deps.IDownloadable;
import org.ultramine.bootstrap.exceptions.ApplicationErrorException;
import org.ultramine.bootstrap.maven.ProjectObjectModel;
import org.ultramine.bootstrap.versioning.DefaultArtifactVersion;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DependencyResolver
{
public static Set<MavenDependency> load(File dir, String selVersion, boolean update, boolean beta, List<URL> extraRepos, List<String> extraLibs)
{
UmSslUtil.checkOrInstall();
File libraryDir = new File(dir, "libraries");
File checkSumsDir = new File(libraryDir, "checksums");
List<IRepository> repositories = new ArrayList<>();
addMavenLocalIfExists(repositories, findMavenLocal());
addMavenLocalIfExists(repositories, findMinecraftLibs());
repositories.addAll(Arrays.asList(
new MavenRemoteRepository("https://repo1.maven.org/maven2"),
new MavenRemoteRepository("https://oss.sonatype.org/content/repositories/snapshots"),
new MavenRemoteRepository("http://files.minecraftforge.net/maven"),
new MavenRemoteRepository("https://libraries.minecraft.net"),
new MavenRemoteRepository("http"+(UmSslUtil.isUseHttps() ? "s" : "")+"://maven.ultramine.ru")
));
for(URL url : extraRepos)
try {
repositories.add(url.getProtocol().equals("file") ? new MavenLocalRepository(new File(url.toURI())) : new MavenRemoteRepository(url.toString()));
} catch(URISyntaxException e) {
throw new ApplicationErrorException(e, "error.addrepo.file", url.toString());
}
System.out.println(I18n.tlt("stage.versions"));
String targetVersion = selVersion;
if(targetVersion == null)
{
List<DefaultArtifactVersion> versions = null;
if(!update)
versions = retrieveLocalVersions(dir);
if(versions == null || versions.size() == 0)
{
UMCoreVersionsRetriever retr = new UMCoreVersionsRetriever();
versions = beta ? retr.getBetaVersions() : retr.getStableVersions();
}
targetVersion = versions.get(versions.size()-1).getLabel();
}
MavenDependency umCoreDep = new MavenDependency(Constants.UM_CORE_GROUP, Constants.UM_CORE_NAME, targetVersion);
File umCoreFile = new File(dir, umCoreDep.getArtifactFilename());
Set<MavenDependency> dependencies = new HashSet<>();
dependencies.addAll(ProjectObjectModel.loadFromArtifact(Constants.UM_REPO, Constants.UM_CORE_GROUP, Constants.UM_CORE_NAME, targetVersion)
.getRuntimeDependencies());
dependencies.addAll(extraLibs.stream().map(MavenDependency::new).collect(Collectors.toList()));
List<IDownloadable> toDownload = dependencies.stream().map(d -> d.resolve(repositories)).collect(Collectors.toList());
IDownloadable umCoreDownloadable = umCoreDep.resolve(repositories);
umCoreDownloadable.setOutputDir(dir);
toDownload.add(umCoreDownloadable);
System.out.println(I18n.tlt("stage.downloading"));
toDownload.parallelStream().forEach(d -> {
try
{
d.setCheckSumsDir(checkSumsDir);
if(d.getOutputDir() == null)
d.setOutputDir(libraryDir);
d.download();
} catch (IOException e) {
throw new ApplicationErrorException(e, "error.download.dependency", d.toString(), e.toString());
}
});
try
{
File symlink = new File(dir, Constants.UM_CORE_NAME+"-latest.jar");
if(symlink.exists())
FileUtils.forceDelete(symlink);
try {
Files.createSymbolicLink(new File(dir, Constants.UM_CORE_NAME + "-latest.jar").toPath(), umCoreFile.toPath());
} catch(IOException e) {
FileUtils.copyFile(umCoreFile, symlink);
}
}
catch(IOException e)
{
throw new ApplicationErrorException(e, "error.write.file", Constants.UM_CORE_NAME+"-latest.jar", e.getMessage());
}
return dependencies;
}
private static List<DefaultArtifactVersion> retrieveLocalVersions(File dir)
{
return Stream.of(dir.list((d, name) -> name.startsWith(Constants.UM_CORE_NAME)))
.map(s -> s.substring(Constants.UM_CORE_NAME.length()+1, s.length()-4))
.map(s -> new DefaultArtifactVersion(s, s)).sorted().collect(Collectors.toList());
}
private static void addMavenLocalIfExists(List<IRepository> list, File repo)
{
if(repo != null && repo.exists())
list.add(new MavenLocalRepository(repo));
}
private static File findMavenLocal()
{
String home = System.getProperty("user.home");
if(home != null)
return new File(home, ".m2"+File.separator+"repository");
return null;
}
private static File findMinecraftLibs()
{
return getFromAppdata(".minecraft"+File.separator+"libraries");
}
private static File getFromAppdata(String name)
{
String osName = System.getProperty("os.name").toLowerCase();
String home = System.getProperty("user.home", ".");
File dir;
if(osName.contains("linux") || osName.contains("unix"))
dir = new File(home, name);
else if(osName.contains("win"))
{
String appdata = System.getenv("APPDATA");
if(appdata != null)
dir = new File(appdata, name);
else
dir = new File(home, name);
}
else if(osName.contains("mac"))
dir = new File(home, "Library/Application Support/" + name);
else
dir = new File(home, name);
return dir;
}
}