/*
 * Copyright 2016 Ali Moghnieh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.blurengine.blur;

import com.google.common.base.Preconditions;

import com.blurengine.blur.modules.framework.ModuleManager;
import com.supaham.commons.bukkit.SimpleCommonPlugin;
import com.supaham.commons.bukkit.TickerTask;
import com.supaham.commons.bukkit.commands.common.CommonCommands;
import com.supaham.commons.bukkit.utils.SerializationUtils;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

import pluginbase.config.datasource.yaml.YamlDataSource;

/**
 * Bukkit plugin class for {@link Blur}.
 */
public class BlurPlugin extends SimpleCommonPlugin<BlurPlugin> {

    private static BlurPlugin instance;

    private Blur blur;
    private RootBlurSession rootSession;

    public static BlurPlugin get() { return instance; }

    public BlurPlugin() {
        Preconditions.checkState(instance == null, "BlurPlugin already initialized.");
        instance = this;
        setSettings(() -> new BlurSettings(this));
    }

    @Override
    public void onEnable() {
        super.onEnable();
        this.blur = new Blur(this);
        this.rootSession = new RootBlurSession(this.blur.getSessionManager());
        ModuleManager moduleManager = this.rootSession.getModuleManager();

        // Load from serialized modules, here's how the whoooole chain starts!
        moduleManager.getModuleLoader().load(getSettings().getModules());

        if (!enableMetrics()) {
            getServer().getPluginManager().disablePlugin(this);
            return;
        }
        CommonCommands.DEBUG.builder(this, "b").register();

        // Immediately load, enable and start the root session to get the wheels going.
        new TickerTask(this, 1, this.rootSession::start).start();
        new TickerTask(this, 200, this.rootSession::stop).start();

        new TickerTask(this, 0, getCommandsManager()::build).start();
    }


    private AtomicInteger tries = new AtomicInteger();

    public BlurSettings getSettings() {
        return (BlurSettings) super.getSettings();
    }

    public Blur getBlur() {
        return blur;
    }

    public RootBlurSession getRootSession() {
        return rootSession;
    }
}

@@ -726,16 +726,136 @@
 anager;%0A
+import com.supaham.commons.bukkit.ServerShutdown;%0Aimport com.supaham.commons.bukkit.ServerShutdown.ServerShutdownEvent;%0A
 import c
@@ -1043,197 +1043,131 @@
 ons.
-bukkit.utils.SerializationUtils;%0A%0Aimport java.io.File;%0Aimport java.io.IOException;%0Aimport java.util.concurrent.atomic.AtomicInteger;%0A%0Aimport pluginbase.config.datasource.yaml.YamlDataSource
+state.State;%0A%0Aimport org.bukkit.event.EventHandler;%0Aimport org.bukkit.event.EventPriority;%0Aimport org.bukkit.event.Listener
 ;%0A%0A/
@@ -1276,16 +1276,36 @@
 rPlugin%3E
+ implements Listener
  %7B%0A%0A    
@@ -1724,24 +1724,291 @@
 onEnable();%0A
+%0A        // This is important for handling immediate shutdown via commands.%0A        ServerShutdown module = new ServerShutdown(getModuleContainer());%0A        getModuleContainer().register(module);%0A        module.setState(State.ACTIVE);%0A        registerEvents(this);%0A%0A
         this
@@ -2830,63 +2830,275 @@
  %7D%0A%0A
-%0A    private AtomicInteger tries = new AtomicInteger();
+    // Cleanup blur during shutdown.%0A    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)%0A    public void onServerShutdown(ServerShutdownEvent event) %7B%0A        if (this.rootSession != null) %7B%0A            this.rootSession.stop();%0A        %7D%0A    %7D
 %0A%0A  

Use ServerShutdown common module to clean up blur during command-shutdowns.