import math
import pandas
from os.path import exists, isfile
from os import mkdir, getcwd
from json import dump
import argparse
import logging
def GenerateJSON(arguments=None):
	parser = argparse.ArgumentParser(description="Generates JSON-files from excel file generated by FromJsonToExcel.py.")
	parser.add_argument('-i', '--input', 
	help="The path to the excel file")
	parser.add_argument('-o', '--output', default=getcwd(), help="Where to make directories which have the JSON files in them (default working directory)")
	parser.add_argument('-c', '--component', help="Optional argument which tells the program to parse only the specified worksheet. If no component is specified, then the \
	program will parse the entire excel file.")
	parser.add_argument('-v', '--verbose', help="Output current file (verbose output)")
	if arguments == None:
		arguments = parser.parse_args()
		arguments = vars(arguments)
	try:
		excel_file = arguments["input"]
		if excel_file == None:
			raise KeyError
	except KeyError:
		print("\n --ERROR-- ")
		print("Input directory not specified. Run 'jhlangtool tojson -i <path to excel file>'")
		print("\n")
		parser.print_help()
		quit()
	if isfile(excel_file) == False:
		print("Invalid path to excel file. Make sure it ends with the .xlsx extension!")
		quit()
	try:
		outputDirs = arguments["output"]
	except KeyError:
		outputDirs = getcwd()
	try:
		arguments["verbose"]
		logging.basicConfig(level=logging.INFO, format='%(message)s')
	except KeyError:
		pass
	try:
		worksheet_name = arguments["component"]
	except KeyError:
		worksheet_name = None
	i = -1
	if not exists(outputDirs):
		mkdir(outputDirs)


	def nested_set(dic, keys, value):
		keys = keys.split('/')
		try:
			for key in keys[:-1]:
				dic = dic.setdefault(key, {})
			dic[keys[-1]] = value
		except AttributeError:
			print("Attribute error", dic, keys, value)


	def value_from_dictionary(dictionary, keys):
		key_list = keys.split('/')
		try:
			for key in key_list:
				dictionary = dictionary[key]
			return dictionary
		except TypeError:
			return {'empty': 'dictionary'}
		except KeyError:
			return {'empty': 'dictionary'}

	def produce_valid_json(dictionary):

		for key in dictionary:
			try:
				if not math.isnan(dictionary [key]):
					return True
			except TypeError:
				return True
		return False

	def add_to_dictionary(dict, language, parent_row, current_row, parent_key_list):
		nonlocal content
		nonlocal number_of_rows
		nonlocal dictionary

		if parent_row>=number_of_rows:
			return parent_row

		row = current_row
		previous_row = row
		previous_key_list = parent_key_list
		key_list = []
		while row < number_of_rows:
			key = content.iat[row, 0]
			key_list = key.split('/')

			if len(key_list) < (len(parent_key_list)+1):
				# vrati se nazad u rekurziji
				return row

			elif (len(key_list) > (len(parent_key_list)+1)) and (row != previous_row):
				# da li se možda nastavlja na prethodni redak?
				if (len(previous_key_list) > 0) and (previous_key_list == key_list[0:len(previous_key_list)]):
					if dict[previous_key_list[-1]] == "":
						dict[previous_key_list[-1]] = {}
					try:
						row = add_to_dictionary(dict[previous_key_list[-1]], language, previous_row, row, previous_key_list)
					except IndexError:
						# print("IndexError", dict, previous_key_list, value, language)
						row = row + 1
				else:
					return row
			else:
				value = content.at[row, language]
				if type(value) == float:
					value = ""

				if (len(parent_key_list)>0) and (parent_key_list == key_list[0:len(parent_key_list)]):
				# ako je key nastavak na parent key
					try:
						if len(key_list)==(len(parent_key_list)+1):
							try:
								dict[key_list[-1]] = value
							except TypeError:
								pass
								# print("TypeError", dict, key_list, value, language)
						else:
							try:
								temp_dict = dict[key_list[len(parent_key_list)]]
							except (IndexError, KeyError):
								try:
									dict[key_list[len(parent_key_list)]] = {}
									temp_dict = dict[key_list[len(parent_key_list)]]
								except TypeError:
									# print("TypeError", dict, key_list, value, language)
									return row+1
							temp_list = previous_key_list
							temp_list.append(key_list[len(parent_key_list)])
							row = add_to_dictionary(temp_dict, language, previous_row, row, temp_list)
					except AttributeError:
						pass
						# print("Attribute error", dict, key, value)
				elif len(key_list) == 1:
					try:
						dict[key_list[-1]] = value
					except AttributeError:
						pass
						# print("Attribute error", dict, key, value)
				else:
					# vrati se nazad u rekurziji
					return row
					# neka nova lista
					# try:
					#     for k in key_list[:-1]:
					#         dict = dict.setdefault(k, {})
					#     dict[key_list[-1]] = value
					# except AttributeError:
					#     print("Attribute error", dict, key, value)
				previous_row = row
				previous_key_list = key_list
				row += 1
		return row

	xls = pandas.ExcelFile(excel_file)
	while True:
		i += 1
		try:
			if worksheet_name:
				try:
					content
					raise IndexError
				except NameError:
					try:
						i = xls.sheet_names.index(worksheet_name)
					except ValueError:
						print("Error: no worksheet named {} found in {}".format(worksheet_name, excel_file))
						return
			content = xls.parse(i)
			file_name = content.columns[0]
			# if file_name == 'metrics.json':
			#     print('metrics.json')
			keyList = []
			logging.info('Created {}'.format(file_name))
			number_of_rows = len(content.index)
			for language in content.columns[1:]:

				dictionary = {}

				add_to_dictionary(dictionary, language, 1, 1, [])
				# create dictionary
				# for row in range(len(content.index)):
				#     value = {}
				#     keys = content.iat[row, 0]
				#     if type(keys) == float:
				#         pass
				#     else:
				#         try:
				#             nested_set(dictionary, keys, value)
				#         except TypeError:
				#             print('Type error', keys, value, language, file_name)
				#
				# # add values to dictionary
				# for row in range(len(content.index)):
				#     value = content.at[row, language]
				#     keys = content.iat[row, 0]
				#     if type(keys) == float:
				#         pass
				#     else:
				#
				#         if type(value) == float:
				#             if len(value_from_dictionary(dictionary, keys)) == 0:
				#                 value = ''
				#                 nested_set(dictionary, keys, value)
				#         else:
				#             try:
				#                 nested_set(dictionary, keys, value)
				#             except TypeError:
				#                 print('Type error', keys, value, language, file_name)

				if not exists(outputDirs + '/' + language):
					mkdir(outputDirs + '/' + language)
				with open(outputDirs + '/' + language + '/' + file_name, mode='w', encoding='utf-8') as data_file:
					if (produce_valid_json(dictionary)):
						dump(dictionary, data_file, ensure_ascii=False, indent=4)
					else:
						logging.info(".. Skipping ", language, file_name)

		except IndexError:
			print('Finished. Root directory is', outputDirs)
			break

if __name__ == '__main__':
	GenerateJSON()