package com.avairebot.orion.database.controllers;

import com.avairebot.orion.Constants;
import com.avairebot.orion.Orion;
import com.avairebot.orion.cache.CacheType;
import com.avairebot.orion.database.collection.DataRow;
import com.avairebot.orion.database.transformers.GuildTransformer;
import com.google.gson.Gson;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.TextChannel;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GuildController {

    private static final String CACHE_STRING = "database.guilds.%s";

    public static GuildTransformer fetchGuild(Orion orion, Message message) {
        if (!message.getChannelType().isGuild()) {
            return null;
        }

        if (isCached(orion, message.getGuild().getId())) {
            return (GuildTransformer) orion.cache.getAdapter(CacheType.MEMORY).get(
                    String.format(CACHE_STRING, message.getGuild().getId())
            );
        }

        try {
            GuildTransformer transformer = new GuildTransformer(orion.database.newQueryBuilder(Constants.GUILD_TABLE_NAME)
                    .where("id", message.getGuild().getId())
                    .get().first());

            if (!transformer.hasData()) {
                final String cacheToken = String.format(CACHE_STRING, message.getGuild().getId());
                try {
                    orion.database.newQueryBuilder(Constants.GUILD_TABLE_NAME)
                            .insert(statement -> {
                                statement.set("id", message.getGuild().getId())
                                        .set("owner", message.getGuild().getOwner().getUser().getId())
                                        .set("name", message.getGuild().getName())
                                        .set("channels_data", buildChannelData(message.getGuild().getTextChannels()));

                                if (message.getGuild().getIconId() != null) {
                                    statement.set("icon", message.getGuild().getIconId());
                                }

                                orion.cache.getAdapter(CacheType.MEMORY)
                                        .put(cacheToken, new GuildTransformer(new DataRow(statement.getItems())), 2);
                            });
                } catch (Exception ex) {
                    orion.logger.fatal(ex);
                }

                return (GuildTransformer) orion.cache.getAdapter(CacheType.MEMORY).get(cacheToken);
            }

            orion.cache.getAdapter(CacheType.MEMORY).put(String.format(CACHE_STRING, message.getGuild().getId()), transformer, 300);

            return transformer;
        } catch (SQLException ex) {
            orion.logger.fatal(ex);
            return null;
        }
    }

    private static boolean isCached(Orion orion, String guildId) {
        return orion.cache.getAdapter(CacheType.MEMORY).has(
                String.format(CACHE_STRING, guildId)
        );
    }

    private static String buildChannelData(List<TextChannel> textChannels) {
        List<Map<String, Object>> channels = new ArrayList<>();
        for (TextChannel channel : textChannels) {
            Map<String, Object> item = new HashMap<>();

            item.put("id", channel.getId());
            item.put("name", channel.getName());
            item.put("position", channel.getPosition());

            channels.add(item);
        }
        return new Gson().toJson(channels);
    }
}

@@ -308,24 +308,68 @@
 .gson.Gson;%0A
+import net.dv8tion.jda.core.entities.Guild;%0A
 import net.d
@@ -862,19 +862,24 @@
     
-if (isCache
+return fetchGuil
 d(or
@@ -893,32 +893,149 @@
 ssage.getGuild()
+);%0A    %7D%0A%0A    public static GuildTransformer fetchGuild(Orion orion, Guild guild) %7B%0A        if (isCached(orion, guild
 .getId())) %7B%0A   
@@ -1163,34 +1163,21 @@
 STRING, 
-message.getG
+g
 uild
-()
 .getId()
@@ -1374,34 +1374,21 @@
 e(%22id%22, 
-message.getG
+g
 uild
-()
 .getId()
@@ -1539,34 +1539,21 @@
 STRING, 
-message.getG
+g
 uild
-()
 .getId()
@@ -1759,34 +1759,21 @@
 t(%22id%22, 
-message.getG
+g
 uild
-()
 .getId()
@@ -1828,34 +1828,21 @@
 owner%22, 
-message.getG
+g
 uild
-()
 .getOwne
@@ -1917,34 +1917,21 @@
 %22name%22, 
-message.getG
+g
 uild
-()
 .getName
@@ -2013,34 +2013,21 @@
 nelData(
-message.getG
+g
 uild
-()
 .getText
@@ -2077,34 +2077,21 @@
     if (
-message.getG
+g
 uild
-()
 .getIcon
@@ -2164,34 +2164,21 @@
 %22icon%22, 
-message.getG
+g
 uild
-()
 .getIcon
@@ -2746,34 +2746,21 @@
 STRING, 
-message.getG
+g
 uild
-()
 .getId()

Add fetch method to guild controller for guild objects