package com.uber.okbuck.core.util;

import com.android.build.gradle.AppPlugin;
import com.android.build.gradle.LibraryPlugin;
import com.uber.okbuck.OkBuckGradlePlugin;
import com.uber.okbuck.core.dependency.DependencyCache;
import com.uber.okbuck.core.model.base.ProjectType;
import com.uber.okbuck.core.model.base.Scope;
import com.uber.okbuck.core.model.base.Target;
import com.uber.okbuck.core.model.base.TargetCache;

import org.gradle.api.Project;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.plugins.GroovyPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.PluginContainer;
import org.gradle.api.plugins.scala.ScalaPlugin;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper;

import java.io.File;
import java.util.Map;

public final class ProjectUtil {

    private ProjectUtil() {}

    public static ProjectType getType(Project project) {
        PluginContainer plugins = project.getPlugins();
        if (plugins.hasPlugin(AppPlugin.class)) {
            return ProjectType.ANDROID_APP;
        } else if (plugins.hasPlugin(LibraryPlugin.class)) {
            return ProjectType.ANDROID_LIB;
        } else if (plugins.hasPlugin(GroovyPlugin.class)) {
            return ProjectType.GROOVY_LIB;
        } else if (plugins.hasPlugin(KotlinPluginWrapper.class)) {
            return ProjectType.KOTLIN_LIB;
        } else if (plugins.hasPlugin(ScalaPlugin.class)) {
            return ProjectType.SCALA_LIB;
        } else if (plugins.hasPlugin(JavaPlugin.class)) {
            return ProjectType.JAVA_LIB;
        } else {
            return ProjectType.UNKNOWN;
        }
    }

    public static DependencyCache getDependencyCache(Project project) {
        return getPlugin(project).depCache;
    }

    public static Map<String, Target> getTargets(Project project) {
        return getTargetCache(project).getTargets(project);
    }

    @Nullable
    public static Target getTargetForOutput(Project targetProject, File output) {
        return getTargetCache(targetProject).getTargetForOutput(targetProject, output);
    }

    public static Map<Project, Map<String, Scope>> getScopes(Project project) {
        return getPlugin(project).scopes;
    }

    static OkBuckGradlePlugin getPlugin(Project project) {
        return project.getRootProject().getPlugins().getPlugin(OkBuckGradlePlugin.class);
    }

    private static TargetCache getTargetCache(Project project) {
        return getPlugin(project).targetCache;
    }

    @Nullable
    static String findVersionInClasspath(Project project, String group, String module) {
        return project.getBuildscript()
                .getConfigurations()
                .getByName("classpath")
                .getIncoming()
                .getArtifacts()
                .getArtifacts()
                .stream()
                .filter(resolvedArtifactResult -> {
                    ModuleComponentIdentifier identifier =
                            (ModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier();
                    return (group.equals(identifier.getGroup()) &&
                            module.equals(identifier.getModule()));
                })
                .findFirst()
                .map(r -> ((ModuleComponentIdentifier) r.getId().getComponentIdentifier()).getVersion())
                .orElse(null);
    }
}

@@ -29,16 +29,92 @@
 .util;%0A%0A
+import java.io.File;%0Aimport java.util.Map;%0Aimport java.util.stream.Stream;%0A%0A
 import c
@@ -140,32 +140,32 @@
 adle.AppPlugin;%0A
-
 import com.andro
@@ -491,17 +491,16 @@
 tCache;%0A
-%0A
 import o
@@ -812,24 +812,24 @@
 s.Nullable;%0A
+
 import org.j
@@ -884,52 +884,8 @@
 r;%0A%0A
-import java.io.File;%0Aimport java.util.Map;%0A%0A
 publ
@@ -2959,23 +2959,16 @@
   .f
-ilter(resolvedA
+latMap(a
 rtif
@@ -2979,18 +2979,16 @@
 esult -%3E
- %7B
 %0A       
@@ -3000,16 +3000,75 @@
         
+artifactResult.getId().getComponentIdentifier() instanceof 
 ModuleCo
@@ -3079,19 +3079,8 @@
 entI
-dentifier i
 dent
@@ -3084,18 +3084,16 @@
 entifier
- =
 %0A       
@@ -3109,20 +3109,28 @@
         
-    
+? Stream.of(
 (ModuleC
@@ -3153,17 +3153,9 @@
 er) 
-resolvedA
+a
 rtif
@@ -3196,17 +3196,17 @@
 tifier()
-;
+)
 %0A       
@@ -3218,22 +3218,75 @@
         
-return
+    : Stream.empty())%0A                .filter(identifier -%3E
  (group.
@@ -3342,20 +3342,16 @@
         
-    
 module.e
@@ -3384,27 +3384,8 @@
 ()))
-;%0A                %7D
 )%0A  
@@ -3436,15 +3436,8 @@
 map(
-r -%3E ((
 Modu
@@ -3461,46 +3461,10 @@
 fier
-) r.getId().getComponentIdentifier()).
+::
 getV
@@ -3469,18 +3469,16 @@
 tVersion
-()
 )%0A      

Fix OkBuck exception when buildscript dependency is Jar (#533)