#!/usr/bin/env python3.5

###############################################################################
#   TransportLayerBot - An all-in-one user bot for Discord.                   #
#   Copyright (C) 2016  TransportLayer                                        #
#                                                                             #
#   This program is free software: you can redistribute it and/or modify      #
#   it under the terms of the GNU Affero 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 Affero General Public License for more details.                       #
#                                                                             #
#   You should have received a copy of the GNU Affero General Public License  #
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
###############################################################################

import logging
import argparse
import discord
import asyncio

def setup_logger(level_string):
	numeric_level = getattr(logging, level_string.upper(), None)
	if not isinstance(numeric_level, int):
		raise Value("Invalid log level: {}".format(level_string))

	log_formatter = logging.Formatter("[%(asctime)s] [%(name)s/%(levelname)s] %(message)s")

	root_logger = logging.getLogger()
	root_logger.setLevel(numeric_level)

	file_logger = logging.FileHandler("TransportLayerBot.log")
	file_logger.setFormatter(log_formatter)
	root_logger.addHandler(file_logger)

	stdout_logger = logging.StreamHandler()
	stdout_logger.setFormatter(log_formatter)
	root_logger.addHandler(stdout_logger)

class Commands():
	@staticmethod
	async def license(client, message, args):
		await client.send_message(message.channel, "I'm licensed under the GNU Affero General Public License.\nFor details, visit: https://www.gnu.org/licenses/agpl.html")

	@staticmethod
	async def source(client, message, args):
		await client.send_message(message.channel, "Get my source code here: https://github.com/TransportLayer/TransportLayerBot-Discord")

	@staticmethod
	async def test(client, message, args):
		await client.send_message(message.channel, "Tested!")

commands = {
	"license": Commands.license,
	"source": Commands.source,
	"test": Commands.test
}

class TransportLayerBot(discord.Client):
	async def on_ready(self):
		logging.info("Logged in as {}, ID {}.".format(self.user.name, self.user.id))

	async def on_message(self, message):
		if not message.author == self.user.id:
			if message.content.startswith('!'):
				command, *args = message.content[1:].split()
				if command in commands:
					try:
						await commands[command](self, message, args)
					except Exception as e:
						await self.send_message(message.channel, "Something broke:\n```{}```".format(e))

def main():
	parser = argparse.ArgumentParser(description="TransportLayerBot for Discord")
	parser.add_argument("-t", "--token", type=str, metavar="TOKEN", dest="TOKEN", help="bot user application token", action="store", required=True)
	parser.add_argument("-l", "--log", type=str, metavar="LEVEL", dest="LOG_LEVEL", help="log level", action="store", default="INFO")
	SETTINGS = vars(parser.parse_args())

	try:
		print("""Welcome to TransportLayerBot!
This software is licensed under the GNU Affero General Public License.
See the LICENSE file for details.
Get the source: https://github.com/TransportLayer/TransportLayerBot-Discord
         _____
        |     |         _______   _
        |_____|        |___ ___| | |           _
           |              | |    | |          / \\
     ______|______        | |    | |         /__/     __/__
  __|__  __|__  __|__     | |    | |___     /  |  _    /
 |     ||     ||     |    |_|    |_____|   /__/  /_/  /
 |_____||_____||_____|
""")

		setup_logger(SETTINGS["LOG_LEVEL"])

		logging.info("Starting TransportLayerBot with Discord version {}.".format(discord.__version__))

		client = TransportLayerBot()
		client.run(SETTINGS["TOKEN"])
	finally:
		logging.info("Stopping.")
		client.logout()

if __name__ == "__main__":
	main()

@@ -1442,16 +1442,170 @@
 syncio%0A%0A
+def safe_string(dangerous_string):%0A%09return dangerous_string.replace('%5Cn', '%5C%5Cn').replace('%5Cr', '%5C%5Cr').replace('%5C033%5B', '%5BCSI%5D').replace('%5C033', '%5BESC%5D')%0A%0A
 def setu
@@ -1628,16 +1628,16 @@
 tring):%0A
-
 %09numeric
@@ -2217,16 +2217,467 @@
 ogger)%0A%0A
+async def send_message(client, source, message):%0A%09logging.debug(%22%7B%7D %7B%7D (%7B%7D #%7B%7D) %3C- %7B%7D%22.format(source.server.id, source.channel.id, source.server.name, source.channel.name, safe_string(message)))%0A%09await client.send_message(source.channel, message)%0A%0Aasync def send_warn(client, source, message):%0A%09logging.warn(%22Unhandled exception: %7B%7D%22.format(safe_string(message)))%0A%09await send_message(client, source, %22Something's wrong...%5Cn%60%60%60%7B%7D%60%60%60%22.format(message))%0A%0A
 class Co
@@ -3307,16 +3307,38 @@
 nds.test
+,%0A%09%22breakthebot%22: None
 %0A%7D%0A%0Aclas
@@ -3783,77 +3783,66 @@
 t se
-lf.send_message(message.channel, %22Something broke:%5Cn%60%60%60%7B%7D%60%60%60%22.format(
+nd_warn(self, message, %22!%7B%7D %7B%7D%5Cn%7B%7D%22.format(command, args, 
 e))%0A

Add logging sent messages functions