package com.demonwav.mcdev.buildsystem.gradle;

import com.demonwav.mcdev.platform.MinecraftModuleType;

import com.google.common.base.Strings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.LibraryDependencyData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

@Order(ExternalSystemConstants.UNORDERED)
public abstract class AbstractDataService extends AbstractProjectDataService<LibraryDependencyData, Module> {

    @NotNull
    private final MinecraftModuleType type;

    public AbstractDataService(@NotNull final MinecraftModuleType type) {
        this.type = type;
    }

    @NotNull
    @Override
    public Key<LibraryDependencyData> getTargetDataKey() {
        return ProjectKeys.LIBRARY_DEPENDENCY;
    }

    @Override
    public void importData(@NotNull Collection<DataNode<LibraryDependencyData>> toImport,
                           @Nullable ProjectData projectData,
                           @NotNull Project project,
                           @NotNull IdeModifiableModelsProvider modelsProvider) {
        if (projectData == null || !projectData.getOwner().equals(GradleConstants.SYSTEM_ID)) {
            return;
        }

        // Set module type accordingly
        Set<Module> goodModules = toImport.stream()
                .filter(n -> n.getData().getExternalName().startsWith(type.getGroupId() + ":" + type.getArtifactId()))
                .map(n -> modelsProvider.findIdeModule(n.getData().getOwnerModule()))
                .distinct()
                .collect(Collectors.toSet());

        // So the way the Gradle plugin sets it up is with 3 modules. There's the parent module, which the Gradle
        // dependencies don't apply to, then submodules under it, normally main and test, which the Gradle dependencies
        // do apply to. We're interested (when setting the module type) in the parent, which is what we do here. The
        // first module should be the parent, but we check to make sure anyways
        ApplicationManager.getApplication().runReadAction(() -> {
            final Module module = modelsProvider.getModules()[0];
            if (module != null) {
                if (goodModules.stream().anyMatch(m -> {
                    String[] paths = ModuleManager.getInstance(project).getModuleGroupPath(m);
                    if (paths != null && paths.length > 0) {
                        if (Arrays.stream(paths).anyMatch(module.getName()::equals)) {
                            return true;
                        }
                    }
                    return false;
                })) {
                    module.setOption("type", type.getId());
                } else {
                    if (Strings.nullToEmpty(module.getOptionValue("type")).equals(type.getId())) {
                        module.setOption("type", JavaModuleType.getModuleType().getId());
                    }
                }
            }
        });
    }
}

@@ -2068,17 +2068,22 @@
  == null
- 
+) %7B //
 %7C%7C !proj
@@ -3133,24 +3133,676 @@
  != null) %7B%0A
+                if (modelsProvider.getModules().length == 1) %7B%0A                    // Okay so all that up there is only one case. The other case is when it's just a single module%0A                    if (goodModules.contains(module)) %7B%0A                        module.setOption(%22type%22, type.getId());%0A                    %7D else %7B%0A                        if (Strings.nullToEmpty(module.getOptionValue(%22type%22)).equals(type.getId())) %7B%0A                            module.setOption(%22type%22, JavaModuleType.getModuleType().getId());%0A                        %7D%0A                    %7D%0A                %7D else %7B%0A                    // This is a group of modules%0A    
             
@@ -3842,24 +3842,28 @@
 atch(m -%3E %7B%0A
+    
             
@@ -3961,24 +3961,28 @@
             
+   
+ 
 if (paths !=
@@ -4006,24 +4006,28 @@
 ngth %3E 0) %7B%0A
+    
             
@@ -4125,24 +4125,28 @@
             
+    
 return true;
@@ -4162,34 +4162,42 @@
                 
+  
-%7D%0A
+  %7D%0A    
                 
@@ -4218,24 +4218,28 @@
             
+    
 return false
@@ -4260,14 +4260,22 @@
     
+ 
+   
 %7D)) %7B%0A
+    
     
@@ -4338,32 +4338,36 @@
                 
+    
 %7D else %7B%0A       
@@ -4371,32 +4371,36 @@
                 
+ 
+   
 if (Strings.null
@@ -4478,32 +4478,36 @@
                 
+    
 module.setOption
@@ -4548,32 +4548,58 @@
 ype().getId());%0A
+                        %7D%0A
                 

Set module type for Gradle projects that only have 1 module