package com.elmakers.mine.bukkit.automata;

import java.util.Collection;
import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;

import com.elmakers.mine.bukkit.api.effect.EffectPlayer;
import com.elmakers.mine.bukkit.api.magic.MageController;
import com.elmakers.mine.bukkit.utility.ConfigurationUtils;

public class AutomatonTemplate {
    @Nonnull
    private final MageController controller;
    @Nonnull
    private final ConfigurationSection configuration;
    @Nonnull
    private final String key;
    private String name;
    private int interval;
    @Nullable
    private Spawner spawner;
    @Nullable
    private Caster caster;
    @Nullable
    private Collection<EffectPlayer> effects;

    public AutomatonTemplate(@Nonnull MageController controller, @Nonnull String key, @Nonnull ConfigurationSection configuration) {
        this.key = key;
        this.controller = controller;
        this.configuration = configuration;
        name = configuration.getString("name");
        interval = configuration.getInt("interval", 0);
        if (configuration.isList("effects")) {
            effects = controller.loadEffects(configuration, "effects");
        } else {
            String effectKey = configuration.getString("effects");
            if (effectKey != null) {
                effects = controller.getEffects(effectKey);
                if (effects.isEmpty()) {
                    effects = null;
                }
            }
        }

        if (configuration.contains("spawn")) {
            spawner = new Spawner(controller, this, configuration.getConfigurationSection("spawn"));
        }

        if (configuration.contains("cast")) {
            caster = new Caster(this, configuration.getConfigurationSection("cast"));
        }
    }

    @Nonnull
    public String getKey() {
        return key;
    }

    @Nullable
    public String getName() {
        return name == null ? key : name;
    }

    public int getInterval() {
        return interval;
    }

    public void tick(Automaton instance) {
        if (spawner != null) {
            List<Entity> entities = spawner.spawn(instance.getLocation());
            if (entities != null && !entities.isEmpty()) {
                instance.track(entities);
            }
            instance.checkEntities();
        }

        if (caster != null) {
            caster.cast(instance.getMage());
        }
    }

    public AutomatonTemplate getVariant(ConfigurationSection parameters) {
        ConfigurationSection mergedConfiguration = ConfigurationUtils.cloneConfiguration(configuration);
        mergedConfiguration = ConfigurationUtils.addConfigurations(mergedConfiguration, parameters);
        return new AutomatonTemplate(controller, key, mergedConfiguration);
    }

    @Nullable
    public Collection<EffectPlayer> getEffects() {
        return effects;
    }
}
@@ -420,16 +420,61 @@
 onUtils;
+%0Aimport com.google.common.base.Preconditions;
 %0A%0Apublic
@@ -664,24 +664,38 @@
 String key;%0A
+    @Nullable%0A
     private 
@@ -1030,19 +1030,47 @@
 s.key = 
+Preconditions.checkNotNull(
 key
+)
 ;%0A      
@@ -2044,39 +2044,38 @@
 y;%0A    %7D%0A%0A    @N
+onn
 ull
-able
 %0A    public Stri
@@ -2085,24 +2085,53 @@
 getName() %7B%0A
+        String name0 = name;%0A
         retu
@@ -2137,16 +2137,17 @@
 urn name
+0
  == null
@@ -2155,24 +2155,25 @@
 ? key : name
+0
 ;%0A    %7D%0A%0A   

Fix nullability of AutomationTemplate#getName