import discord
import sqlite3 as sql
import logging
import cleverbot
import random
logging.basicConfig(level=logging.INFO)
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
from apiclient.discovery import build
import apiclient.errors
# Please refer to the README to find where you should paste your bot's credentials for services.
blacklistwords = ['image','gif','help','add','talk','permissions','blacklist','whitelist']
maxwhiterank = 3
maxblackrank = 3

service = build("customsearch", "v1",
               developerKey="CREATE FROM CONSOLE.DEVELOPERS.GOOGLE.COM")

class client(discord.Client):
	def isBlacklisted(self,msg,p):
		c.execute("SELECT level FROM blacklist where id = ?", (msg.author.id,))
		blacklist = c.fetchone()
		if blacklist:
			val = int(blacklist[0][0])
			if val >= int(p):
				self.send_message(msg.channel,'%s is blacklist level %s, therefore this command is locked.' % (msg.author.name, blacklist[0][0]))
				return True
			else:
				return False
		else:
			return False

	def isWhitelisted(self,msg,p):
		c.execute("SELECT level FROM whitelist where id = ?", (msg.author.id,))
		whitelist = c.fetchone()
		if whitelist:
			val = int(whitelist[0][0])
			if val >= int(p):
				return True
			else:
				self.send_message(msg.channel,'%s does not have sufficient permissions to use that command.' % msg.author.name)
				return False
		else:
			self.send_message(msg.channel,'%s does not have sufficient permissions to use that command.' % msg.author.name)
			return False

	def on_message(self, message):
		p = self.isBlacklisted(message,'3')
		if p == False:
			if message.content.startswith('$help'):
				commands = c.execute('SELECT name FROM cmds')
				self.send_message(message.channel,
				"""py2discord is a Discord chat bot written in Python 
by https://github.com/shiburizu/""" % ', '.join([str(i[0])for i in commands]))
			elif message.content.startswith('$blacklist '):
				try:
					p = self.isWhitelisted(message,'1') #check whitelist 1
					if p == True:
						insert = (message.content[13:].replace('>','')).split(' ', 1)
						try:
							if insert[1].isdigit():
								print insert
								if int(insert[1]) > maxblackrank:
									self.send_message(message.channel, 'Please provide a valid blacklist level. Can be from 0 (None) to %s.' % maxblackrank)
								else:
									c.execute('INSERT OR REPLACE INTO blacklist(id, level) VALUES(?,?)',
									(insert[0],insert[1]))
									db.commit()
									self.send_message(message.channel, 
									'Successfully blacklisted ID %s at level %s.' % (insert[0],insert[1]))
							else:
								self.send_message(message.channel, 'Please provide a valid blacklist level. Can be from 0 (None) to %s.' % maxblackrank)

						except IndexError:
							self.send_message(message.channel, 'Please provide a valid blacklist level. Can be from 0 (None) to %s.' % maxblackrank)
				except sql.Error as e:
					if db:
						db.rollback()
					print "Error %s:" % e.args[0]
					self.send_message(message.channel, 
					"Something went wrong. It has been logged.")

			elif message.content.startswith('$whitelist '):
				try:
					p = self.isWhitelisted(message,'2') #check whitelist 2
					if p == True:
						insert = (message.content[13:].replace('>','')).split(' ', 1)
						try:
							if insert[1].isdigit():
								print insert
								if int(insert[1]) > maxwhiterank:
									self.send_message(message.channel, 'Please provide a valid whitelist level. Can be from 0 (None) to %s.' % maxwhiterank)
								else:
									c.execute('INSERT OR REPLACE INTO whitelist(id, level) VALUES(?,?)',
									(insert[0],insert[1]))
									db.commit()
									self.send_message(message.channel, 
									'Successfully whitelisted ID %s at level %s.' % (insert[0],insert[1]))
							else:
								self.send_message(message.channel, 'Please provide a valid whitelist level. Can be from 0 (None) to %s.' % maxwhiterank)

						except IndexError:
							self.send_message(message.channel, 'Please provide a valid whitelist level. Can be from 0 (None) to %s.' % maxwhiterank)
				except sql.Error as e:
					if db:
						db.rollback()
					print "Error %s:" % e.args[0]
					self.send_message(message.channel, 
					"Something went wrong. It has been logged.")

			elif message.content.startswith('$image '):
				try:
					p = self.isBlacklisted(message,'1') #check blacklist 1
					if p == False:
						query = message.content[7:]
						if query != '':
							res = service.cse().list(
							q=query,
							cx='INSERT CX KEY FROM CSE.GOOGLE.COM',
							searchType='image',
							num=10,
							safe='off'
							).execute()	
						if not 'items' in res:
							self.send_message(message.channel, "No image found.")
						else:
							results = []
							for item in res['items']:
								results.append(item['link'])
							self.send_message(message.channel, random.choice(results))
					else:
						self.send_message(message.channel,'Please input search terms.')

				except apiclient.errors.HttpError as e:
					self.send_message(message.channel,
					"There was a problem with your request. Here is some information:```%s```" % e)

			elif message.content.startswith('$gif '):
				try:
					p = self.isBlacklisted(message,'1') #check blacklist 1
					if p == False:
						query = message.content[7:]
						if query != '' or None:
							res = service.cse().list(
							q=query,
							cx='INSERT CX KEY FROM CSE.GOOGLE.COM',
							searchType='image',
							fileType='gif',
							num=10,
							safe='off'
							).execute()	
							if not 'items' in res:
								self.send_message(message.channel, "No image found.")
							else:
								results = []
								for item in res['items']:
									results.append(item['link'])
								self.send_message(message.channel, random.choice(results))
					else:
						self.send_message(message.channel,'Please input search terms.')
				except apiclient.errors.HttpError as e:
					self.send_message(message.channel, 
					"There was a problem with your request. Here is some information:```%s```" % e)
					
			elif message.content.startswith('$add '):
				try:
					p = self.isBlacklisted(message,'2')
					if p == False:
						insert = (message.content[5:].encode('utf-8')).split(' ', 1)
						if not insert in blacklistwords:
							print insert
							c.execute('INSERT OR ABORT INTO cmds(name,cmd) VALUES(?,?)',
							(insert[0],insert[1]))
							db.commit()
							self.send_message(message.channel, 
							"Command added.")
						else:
							self.send_message(message.channel, 
							"This is a blacklisted word, and cannot be added.")
				except sql.IntegrityError:
					self.send_message(message.channel, "Already exists. Aborted.")
				except sql.Error as e:
					if db:
						db.rollback()
					print "Error %s:" % e.args[0]
					self.send_message(message.channel, 
					"Something went wrong. It has been logged.")

			elif message.content.startswith('$talk '):
				reply = talk.ask(message.content[6:])
				print "Was asked:", message.content[6:], "Replied with:", reply
				self.send_message(message.channel, reply)
					
			elif message.content.startswith('$permissions'):
				c.execute('SELECT level FROM whitelist WHERE id = ?', (message.author.id,))
				white = c.fetchone()
				if not white:
					white = 0
				else:
					white = white[0][0]
				c.execute('SELECT level FROM blacklist WHERE id = ?', (message.author.id,))
				black = c.fetchone()
				if not black:
					black = 0
				else:
					black = black[0][0]
				self.send_message(message.channel,
				'%s, your Discord ID is %s. Your whitelist level is %s and blacklist level is %s.' % (
				message.author.name,message.author.id,white,black))

			elif message.content.startswith('$'):
				try:
					c.execute("SELECT cmd FROM cmds WHERE name = ?", 
					(message.content[1:],))
					fetch = c.fetchone()
					self.send_message(message.channel, fetch[0])
				except TypeError:
					pass

talk = cleverbot.Cleverbot()	
bot = client()
db = sql.connect('commands.db')
db.text_factory = str
c = db.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS cmds(name VARCHAR(10) UNIQUE, 
cmd VARCHAR(64));''')
c.execute('''CREATE TABLE IF NOT EXISTS blacklist(id VARCHAR(10) UNIQUE, 
level VARCHAR(64));''')
c.execute('''CREATE TABLE IF NOT EXISTS whitelist(id VARCHAR(10) UNIQUE, 
level VARCHAR(64));''')
db.commit()
bot.login('EMAIL','PASSWORD')
bot.run()
