/*
 * SlackMc Bukkit/Bungeecord Api - Bukkit/Bungeecord plugin for Slack
 *      Copyright (C) 2016  putzi_x  (http://putzi.xyz)
 *
 *      This program is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 */

package xyz.putzi.slackmc.bungeecord.check;


import xyz.putzi.slackmc.bungeecord.SlackMcPlugin;
import xyz.putzi.slackmc.bungeecord.check.player.PlayerChat;
import xyz.putzi.slackmc.bungeecord.check.player.PlayerIp;

import java.util.Objects;

public enum RegisteredChecks {

    PLAYER_CHAT(PlayerChat.class),
    PLAYER_IP(PlayerIp.class);

    private final Class<? extends BaseCheck> clazz;
    private BaseCheck check;

    RegisteredChecks(Class<? extends BaseCheck> clazz) {
        this.clazz = Objects.requireNonNull(clazz, "Clazz must not be null.");
    }

    public void init() {
        if (clazz.getDeclaringClass() != null)
            throw new UnsupportedOperationException("RegisteredChecks must be defined in their own classes!");
        Check data = clazz.getDeclaredAnnotation(Check.class);
        if (data == null)
            throw new UnsupportedOperationException("Missing @Check annotation!");
        try {
            this.check = clazz.newInstance();
            this.check.data = new CheckData(data.id(), data.name(), data.enabled(), data.category());
        } catch (IllegalAccessException | InstantiationException ignored) {
            throw new RuntimeException("Missing default constructor");
        }
    }

    public void load() {
        if (check == null)
            throw new IllegalStateException("Check hast not been initialized yet!");
        if (check.isEnabled()) {
            check.onLoad();
            check.registerEvents();
            check.registerCommands();
            SlackMcPlugin.LOGGER.info("[CHECKS] check '" + check.getName() + "' loaded!");
        }
    }

    public void unload() {
        if (check == null)
            throw new IllegalStateException("Check hast not been initialized yet!");
        if (check.isEnabled()) {
            check.onUnload();
            SlackMcPlugin.LOGGER.info("[CHECKS] check '" + check.getName() + "' unloaded!");
        }
    }

    public void reload() {
        if (check == null) {
            throw new IllegalStateException("Check hast not been initialized yet!");
        }
        if (check.isEnabled()) {
            check.onReload();
            SlackMcPlugin.LOGGER.info("[CHECKS] check '" + check.getName() + "' reloaded!");
        }
    }

    public static void registerAll() {
        for (RegisteredChecks check : values())
            check.init();
        for (RegisteredChecks check : values())
            check.load();
    }

    public static void unregisterAll() {
        for (RegisteredChecks check : values())
            check.unload();
    }

    public static void reloadAll() {
        for (RegisteredChecks check : values())
            check.reload();
    }
}
