import logging

import argparse
from sleekxmpp import ClientXMPP
from sleekxmpp.exceptions import IqError, IqTimeout
import os, subprocess
import urllib.request
import datetime
import ssl
from PIL import Image
from pprint import pprint

# python3 streambot.py -j streambot@vvvvvvaria.org -p ******* -m test@muc.vvvvvvaria.org -o ./stream/

# rewrite script to work with slixmpp >>> https://slixmpp.readthedocs.io/getting_started/muc.html

parser = argparse.ArgumentParser()
parser.add_argument("-j", "--jid", help="jabber identifier", type=str, required=True)
parser.add_argument("-p", "--password", help="password", type=str, required=True)
parser.add_argument("-m", "--muc", help="destination muc", type=str, required=True)
parser.add_argument("-n", "--nick", help="nickname of the bot", default="streambot", type=str)
parser.add_argument("-o", "--output", help="output folder", default="./stream/", type=str)
args = parser.parse_args()

# This was a useful tutorial: http://sleekxmpp.com/getting_started/echobot.html#echobot

class ArchivistBot(ClientXMPP):

	def __init__(self, jid, password, room, nick, output):
		ClientXMPP.__init__(self, jid, password)

		self.datadir = output
		self.room = room
		self.nick = nick

		self.add_event_handler("session_start", self.session_start) 
		self.add_event_handler("message", self.archive_msg) # by using 'message' instead of 'groupchat_message' every message received can be archived (also personal msgs)
		
		# self.add_event_handler("groupchat_message", self.archive_msg2)

		self.register_plugin('xep_0045')
		self.register_plugin('xep_0030')
		self.register_plugin('xep_0084')
		self.register_plugin('xep_0096') # Transfer files..
		self.register_plugin('xep_0066') # Transfer files..

	def session_start(self, event):
		roster = self.get_roster()
		print('\nRoster:', roster)

		self.send_presence()

		self.plugin['xep_0045'].joinMUC(self.room, self.nick) # MUC plugin

		with open('avatar.png', 'rb') as avatar_file:
			avatar = avatar_file.read()
		avatar_id = self['xep_0084'].generate_id(avatar)
		info = {
			'id': avatar_id,
			'type': 'image/png',
			'bytes': len(avatar)
			}
		self['xep_0084'].publish_avatar(avatar)
		self['xep_0084'].publish_avatar_metadata(items=[info])

		# XEP-0153: vCard-Based Avatars
		# Not working ATM

		self['xep_0153'].set_avatar(avatar=avatar, mtype='image/png')

	def archive_msg(self, msg):
		print('\nMessage:{}'.format(msg))
		print('\nMessage TYPE:{}'.format(msg['type']))
		print('\nMessage OOB:{}'.format(msg['oob']))
		print('\nMessage OOB URL:{}'.format(msg['oob']['url']))
		print('\nMessage MUCK NICK:{}'.format(msg['mucnick']))

		# Always check that a message is not the bot itself, otherwise you will create an infinite loop responding to your own messages.
		if msg['mucnick'] != self.nick:

			if msg['type'] in ('groupchat', 'normal'):

				# only works if messages are not encrypted
				if len(msg['oob']['url']) > 0:

					# logging.getLogger().debug("received OOB from %s with %s" % (self.nick, msg['oob']['url']))

					filename = os.path.basename(msg['oob']['url'])
					targetDir = self.datadir
					if not os.path.exists(targetDir):
						os.mkdir(targetDir, '0755')

					targetFile = os.path.join(targetDir, filename)
					print('\n targetFile', targetFile)

					#needed to disable certificate validation:
					ctx = ssl.create_default_context()
					ctx.check_hostname = False
					ctx.verify_mode = ssl.CERT_NONE

					# save image to file
					# urllib.request.urlretrieve(msg['oob']['url'], targetFile, context=ctx)
					# with urllib.request.urlopen(msg['oob']['url'], context=ctx) as u, \
						# open(targetFile, 'w+') as f:
							# f.write(u.read())
							# f.close()
					
					# Download the file from `url` and save it locally under `file_name`:
					with urllib.request.urlopen(msg['oob']['url']) as response:
						data = response.read() # a `bytes` object
						f = open(targetFile, 'wb')
						f.write(data)
					logging.getLogger().debug("saved to %s" % targetFile)

					# subprocess.call(["make","publish"], cwd="/srv/gitea/clones/varia.website/")

				msg.reply("Thanks for sending! I will store that for you." % msg).send() # works! also for omemo messages, but it cannot decrypt them.



if __name__ == '__main__':
	# Ideally use optparse or argparse to get JID,
	# password, and log level.

	logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
	
	client = ArchivistBot(args.jid, args.password, args.muc, args.nick, args.output)

	if client.connect():
		client.process(block=True)
	else:
		logging.getLogger().error("Can't connect.")