package netflix.nebula.dependency.recommender.provider;

import org.apache.commons.io.IOUtils;
import org.gradle.api.Project;
import org.gradle.mvn3.org.apache.maven.model.Dependency;
import org.gradle.mvn3.org.apache.maven.model.Model;
import org.gradle.mvn3.org.apache.maven.model.building.*;
import org.gradle.mvn3.org.apache.maven.model.interpolation.StringSearchModelInterpolator;
import org.gradle.mvn3.org.apache.maven.model.path.DefaultPathTranslator;
import org.gradle.mvn3.org.apache.maven.model.path.DefaultUrlNormalizer;
import org.gradle.mvn3.org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.gradle.mvn3.org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
import org.gradle.mvn3.org.codehaus.plexus.interpolation.ValueSource;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MavenBomRecommendationProvider extends FileBasedRecommendationProvider {
    private Map<String, String> recommendations;

    public MavenBomRecommendationProvider(Project project) {
        super(project);
    }

    @Override
    public String getVersion(String org, String name) throws Exception {
        if(recommendations == null) {
            recommendations = new HashMap<>();
            DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
            request.setModelSource(new StringModelSource(IOUtils.toString(getInput(), "UTF-8")));

            DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
            modelBuilder.setModelInterpolator(new ProjectPropertiesModelInterpolator(project));

            ModelBuildingResult result = modelBuilder.build(request);
            for (Dependency d : result.getEffectiveModel().getDependencyManagement().getDependencies()) {
                recommendations.put(d.getGroupId() + ":" + d.getArtifactId(), d.getVersion());
            }
        }
        return recommendations.get(org + ":" + name);
    }

    @SuppressWarnings("unchecked")
    @Override
    public InputStreamProvider setModule(Object dependencyNotation) {
        if(dependencyNotation instanceof String && !((String) dependencyNotation).endsWith("@pom"))
            dependencyNotation = dependencyNotation + "@pom";
        if(dependencyNotation != null && Map.class.isAssignableFrom(dependencyNotation.getClass()))
            ((Map) dependencyNotation).put("ext", "pom");
        return super.setModule(dependencyNotation);
    }

    private static class ProjectPropertiesModelInterpolator extends StringSearchModelInterpolator {
        private final Project project;

        ProjectPropertiesModelInterpolator(Project project) {
            this.project = project;
            setUrlNormalizer(new DefaultUrlNormalizer());
            setPathTranslator(new DefaultPathTranslator());
        }

        public List<ValueSource> createValueSources(Model model, File projectDir, ModelBuildingRequest request, ModelProblemCollector collector) {
            List<ValueSource> sources = new ArrayList<>();
            sources.add(new MapBasedValueSource(project.getProperties()));
            sources.add(new PropertiesBasedValueSource(System.getProperties()));
            sources.addAll(super.createValueSources(model, projectDir, request, collector));
            return sources;
        }
    }
}

@@ -54,46 +54,8 @@
 r;%0A%0A
-import org.apache.commons.io.IOUtils;%0A
 impo
@@ -81,16 +81,16 @@
 roject;%0A
+
 import o
@@ -743,16 +743,72 @@
 o.File;%0A
+import java.io.IOException;%0Aimport java.io.InputStream;%0A
 import j
@@ -1380,24 +1380,25 @@
 gRequest();%0A
+%0A
             
@@ -1424,22 +1424,16 @@
 rce(new 
-String
 ModelSou
@@ -1440,46 +1440,305 @@
 rce(
-IOUtils.toString(getInput(), %22UTF-8%22))
+) %7B%0A                @Override%0A                public InputStream getInputStream() throws IOException %7B%0A                    return getInput();%0A                %7D%0A%0A                @Override%0A                public String getLocation() %7B%0A                    return null;%0A                %7D%0A            %7D
 );%0A%0A

Remove dependency on IOUtils