const Config = require('./config/config');
const Servers = require('./config/servers');
const Discord = require('discord.js');
const Rcon = require('rcon');
const Query = require("minecraft-query");
const Server = require('./includes/class_server');
const FS = require('fs');

const client = new Discord.Client();

client.on('ready', () => {
    console.log(`Logged in as ${client.user.tag}!`);
});

process.on('SIGINT', function() {
    console.log("Closing down...");
    process.exit(1);
});

function sendOnline(status, channel) {
    let playerCount = 0;
    let embed = new Discord.MessageEmbed()
        .setThumbnail("https://www.circlecraft.info/images/circlecraft_discord.png")
        .setColor(0x44ff44);
    for ( const s in status ) {
        if ( !status[s].tested ) {
            return;
        }
        if ( status[s].players.length > 0 ) {
            playerCount += status[s].players.length;
            embed.addField("**" + status[s].name + "**:", status[s].players.join(', '), false);
        }
    };
    embed.setTitle("**Players Currently Online:** " + playerCount);
    channel.send(embed);
}

client.on('message', async msg => {
    if ( msg.content.startsWith(">>paddle") ) {
        console.log("Trying to paddle");
        if ( msg.member.roles.cache.has(Config.MOD_ROLE) || msg.member.roles.cache.has(Config.STAFF_ROLE) ) {
            let response = "";
            msg.mentions.users.forEach(function (user) {
                response += "<@" + user.id + "> ";
            });
            response += "Don't do bad things!";
            msg.channel.send(response, { files: ["images/paddlin_badge.png"] });
        }
    }

    if ( msg.content.startsWith(">>servers") && Config.CHANNELS_ALLOW.includes(msg.channel.id) ) {
        let embed = new Discord.MessageEmbed()
            .setTitle("Here's a list of our current servers...")
            .setColor(0xFFaaaa);
        Servers.forEach(function (server) {
            if ( server.active ) embed.addField("**" + server.name + "** *(" + server.slug + ")*", server.description);
        });
        embed.setFooter("Get more info on a pack with: >>server slug\nThe slugs are in parenthesis above");

        msg.channel.send(embed);
    }

    if ( msg.content == ">>online" && Config.CHANNELS_ALLOW.includes(msg.channel.id) ) {
        let status = [];
        Servers.forEach(function (server) {
            if ( server.active ) {
                status[server.slug] = {tested: false, online: false, players: [], name: ""};
                status[server.slug].name = server.name;
            }
        });
        Servers.forEach(function (server) {
            if ( !status[server.slug] ) return;
            const q = new Query({host: server.rconAddress, port: server.queryPort, timeout: 250});
            try {
                q.fullStat()
                    .then(response => {
                        status[server.slug].tested = true;
                        status[server.slug].online = true;
                        status[server.slug].players = response.players;
                        sendOnline(status, msg.channel);
                    })
                    .then(() => { q.close(); })
                    .catch(e => {
                        q.close();
                        console.log("slug: " + server.slug);
                        console.log(status);
                        status[server.slug].tested = true;
                        sendOnline(status, msg.channel);
                    });
            } catch (e) {
                console.log(e);
            }
        });
    }

    if ( msg.content == ">>server" && Config.CHANNELS_ALLOW.includes(msg.channel.id) ) {
        msg.channel.send("**Usage:** >>server *slug*");
    }

    if ( msg.content.startsWith(">>restart") && Config.CHANNELS_ALLOW.includes(msg.channel.id) ) {
        if ( msg.member.roles.cache.has(Config.RESTART_ROLE) ) {
            let cmdParts = msg.content.trim().split(" ");
            let server = Servers.find(element => element.slug == cmdParts[1].trim());
            if ( typeof server === 'undefined' ) {
                msg.channel.send("**Error:** There is no server with a slug of \"`" + cmdParts[1].trim() + "`\"");
            } else {
                let restartFile = '/automation/mcrestart/' + server.slug + '.restart';
                FS.stat(restartFile, function(err, stat) {
                    if ( err == null ) {
                        msg.channel.send("**Warning:** " + server.name + " is already queued for a restart");
                    } else if ( err.code === 'ENOENT' ) {
                        FS.closeSync(FS.openSync(restartFile, 'w'));
                        msg.channel.send("**Notice:** " + server.name + " queued for restart by " + msg.author.username);
                    }
                });
            }
        } else {
            msg.channel.send("**Error:** You do not have permission to restart servers");
        }
    }

    if ( msg.content.startsWith(">>server ") && Config.CHANNELS_ALLOW.includes(msg.channel.id) ) {
        let cmdParts = msg.content.trim().split(" ");
        let server = Servers.find(element => element.slug == cmdParts[1].trim());
        if ( server ) {
            let hostStatus = "Offline";
            if (server.hostIsAlive()) hostStatus = "Online";
            let serverStatus = "Stopped";
            let serverTPS = "---";
            if ( (hostStatus == "Online") && (server.rconPort != 0) ) {
                var rcon = new Rcon(server.rconAddress, server.rconPort, server.rconPassword);
		        rcon.on('auth', function() {
                    serverStatus = "Running";
                    rcon.send(server.rconTPSCommand);
                }).on('response', function(response) {
                    if ( ['1.2.5', '1.4.7'].includes(server.mcVersion) ) {
                        let tpsParts = response.trim().split("\n");
                        serverTPS = tpsParts[0].split(" ").pop().slice(2);
                    } else {
                        let tpsParts = response.trim().split(" ");
                        serverTPS = tpsParts.pop();
                        if ( serverTPS.includes("*") ) serverTPS = serverTPS.split("*").pop();
                    }
                    const q = new Query({host: server.rconAddress, port: server.queryPort, timeout: 250});
                    try {
                        q.fullStat()
                            .then(response => {
                                server.sendDetails(msg.channel, hostStatus, serverStatus, serverTPS, response);
                            })
                            .then(() => { q.close(); })
                            .catch(e => {
                                q.close();
                                server.sendDetails(msg.channel, hostStatus, serverStatus, serverTPS);
                            });
                    } catch (e) {
                        console.log(e);
                    }
                }).on('error', function(err) {
                    console.log("RCon Error connecting to '" + server.slug + "': " + err);
                    server.sendDetails(msg.channel, hostStatus, serverStatus, serverTPS);
                }).on('end', function() {
                    console.log("RCon connection to '" + server.slug + "' Failed for some unknown reason");
                    server.sendDetails(msg.channel, hostStatus, serverStatus, serverTPS);
                });
                rcon.connect();
            } else {
                if ( server.rconPort != 0 ) {
                    console.log("No rcon settings for: " + server.name);
                }
                server.sendDetails(msg.channel, hostStatus, serverStatus, serverTPS);
            }
        } else {
            if ( cmdParts[1] ) {
                msg.channel.send("No server with the slug \"`" + cmdParts[1] + "`\" exists");
            } else {
                msg.channel.send("**Usage:** >>server *slug*");
            }
        }
    }

});

client.login(Config.BOT_TOKEN);

// vim: set ts=4 sw=4: