package com.demonwav.mcdev.platform.bukkit;

import com.demonwav.mcdev.buildsystem.BuildSystem;
import com.demonwav.mcdev.buildsystem.SourceType;
import com.demonwav.mcdev.platform.AbstractModule;
import com.demonwav.mcdev.platform.PlatformType;
import com.demonwav.mcdev.platform.bukkit.yaml.PluginConfigManager;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.Icon;

public class BukkitModule<T extends BukkitModuleType> extends AbstractModule {

    private VirtualFile pluginYml;
    private PlatformType type;
    private PluginConfigManager configManager;
    private T moduleType;

    BukkitModule(@NotNull Module module, @NotNull T type) {
        this.moduleType = type;
        this.type = type.getPlatformType();
        this.module = module;
        buildSystem = BuildSystem.getInstance(module);
        if (buildSystem != null) {
            if (!buildSystem.isImported()) {
                buildSystem.reImport(module).done(buildSystem  -> {
                    pluginYml = buildSystem.findFile("plugin.yml", SourceType.RESOURCE);

                    if (pluginYml != null) {
                        this.configManager = new PluginConfigManager(this);
                    }
                });
            }
        }
    }

    private BukkitModule(@NotNull Module module, @NotNull T type, @Nullable BuildSystem buildSystem) {
        this.moduleType = type;
        this.type = type.getPlatformType();
        this.module = module;
        this.buildSystem = buildSystem;
        if (this.buildSystem == null) {
            // set up build system
            this.buildSystem = BuildSystem.getInstance(module);
            if (this.buildSystem != null) {
                // a valid build system was detected, import it
                if (!this.buildSystem.isImported()) {
                    this.buildSystem.reImport(module).done(b -> {
                        pluginYml = b.findFile("plugin.yml", SourceType.RESOURCE);
                        if (pluginYml != null) {
                            this.configManager = new PluginConfigManager(this);
                        }
                    });
                }
            }
        }
    }

    @Nullable
    public PluginConfigManager getConfigManager() {
        if (configManager == null) {
            if (pluginYml != null) {
                configManager = new PluginConfigManager(this);
            }
        }
        return configManager;
    }

    public VirtualFile getPluginYml() {
        if (pluginYml == null && buildSystem != null) {
            // try and find the file again if it's not already present
            // when this object was first created it may not have been ready
            pluginYml = buildSystem.findFile("plugin.yml", SourceType.RESOURCE);
        }
        return pluginYml;
    }

    @Override
    public Icon getIcon() {
        return type.getType().getIcon();
    }

    @Override
    public T getModuleType() {
        return moduleType;
    }

    private void setModuleType(T moduleType) {
        this.moduleType = moduleType;
    }

    @Override
    public PlatformType getType() {
        return type;
    }

    private void setType(PlatformType type) {
        this.type = type;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        BukkitModule that = (BukkitModule) o;

        return module.equals(that.module);
    }

    @Override
    public int hashCode() {
        return module.hashCode();
    }

    @Override
    public boolean isEventClassValid(PsiClass eventClass, PsiMethod method) {
        return "org.bukkit.event.Event".equals(eventClass.getQualifiedName());
    }

    @Override
    public String writeErrorMessageForEventParameter(PsiClass eventClass, PsiMethod method) {
        return "Parameter is not a subclass of org.bukkit.event.Event\n" +
                "Compiling and running this listener may result in a runtime exception";
    }
}

@@ -1189,926 +1189,171 @@
     
- pluginYml = buildSystem.findFile(%22plugin.yml%22, SourceType.RESOURCE);%0A%0A                    if (pluginYml != null) %7B%0A                        this.configManager = new PluginConfigManager(this);%0A                    %7D%0A                %7D);%0A            %7D%0A        %7D%0A    %7D%0A%0A    private BukkitModule(@NotNull Module module, @NotNull T type, @Nullable BuildSystem buildSystem) %7B%0A        this.moduleType = type;%0A        this.type = type.getPlatformType();%0A        this.module = module;%0A        this.buildSystem = buildSystem;%0A        if (this.buildSystem == null) %7B
+setup();%0A                %7D);%0A            %7D else %7B%0A                setup();%0A            %7D%0A        %7D
 %0A    
-  
+%7D%0A%0A
     
-  // set up build system%0A            this.buildSystem = BuildSystem.getInstance(module);%0A            if (this.buildSystem != null) %7B%0A                // a valid build system was detected, import it%0A                if (!this.buildSystem.isImported()) %7B%0A                    this.buildSystem.reImport(module).done(b -%3E %7B%0A                        pluginYml = b
+public void setup() %7B%0A        pluginYml = buildSystem
 .fin
@@ -1394,32 +1394,17 @@
 OURCE);%0A
-                
+%0A
         
@@ -1428,32 +1428,16 @@
 null) %7B%0A
-                
         
@@ -1496,90 +1496,8 @@
 s);%0A
-                        %7D%0A                    %7D);%0A                %7D%0A            %7D%0A
     

Fix Bukkit module not totally initializing