# Loads the disc settings from loot table and sounds.json files and saves in discs.json
import json
import os


# THIS PYTHON CODE NEEDS TO BE EXECUTED FROM PATH OF THIS DATAPACK

DATA_PATH = 'data/murderdrones/'
DISCS_PATH = DATA_PATH + 'functions/discs/'
LOOT_PATH = DATA_PATH + 'loot_tables/items/'

PREFIX = 'music_disc_'
CUSTOM_MODEL_DATA_ID = 1650000
RESOURCEPACK_PATH = os.path.abspath('../../../../resourcepacks/Murder-Drones-Origins-Resource-Pack')
# RESOURCEPACK_PATH = r'C:\Users\Jan\AppData\Roaming\ModrinthApp\profiles\Murder Drones\resourcepacks\Murder-Drones-Origins-Resource-Pack'
VOLUME_OVERRIDES = {
	'bite_me': 6,
	'kingslayer': 6
}

SOUNDS_PATH = RESOURCEPACK_PATH + '/assets/murderdrones/'.replace('/', os.sep)
RECORDS_PATH = SOUNDS_PATH + 'sounds/records/'.replace('/', os.sep)

def get_primitive_tag_key(tag: str, key: str) -> str:
	start = tag.find(key)
	start += tag.find(':', start) + 1
	end = min(abs(tag.find(',', start)), abs(tag.find('}', start)))
	return tag[start:end].strip()

def pop_primitive_tag_key(tag: str, key: str) -> tuple[str, str]:
	begin = tag.find(key)
	start = tag.find(':', begin) + 1
	end = min(abs(tag.find(',', start)), abs(tag.find('}', start)))
	value = tag[start:end].strip()
	tag = tag[:begin] + tag[end:]
	return tag, value

# Discs are loaded from loot tables
if __name__ == '__main__':
	files = os.listdir(LOOT_PATH)
	disc_files = filter(lambda file: file.startswith(PREFIX), files)
	disc_files = [file[len(PREFIX):-5] for file in disc_files]
	sounds_file = json.load(open(SOUNDS_PATH + 'sounds.json', encoding='UTF-8'))
	# for i, file in enumerate(disc_files):
	# 	print(f'{i}: {file}')
	discs = [{}] * len(disc_files)
	for disc_file in disc_files:
		disc_index: int
		nbt: str = None
		name: dict | str
		description: str
		with open(LOOT_PATH+PREFIX+disc_file+'.json', encoding='UTF-8') as file:
			functions = json.load(file)['pools'][0]['entries'][0]['functions']
			for function in functions:
				match function['function']:
					case 'set_name' | 'minecraft:set_name':
						name = function['name']
						if type(name) is dict:
							if 'italic' in name and name['italic'] == False:
								name.pop('italic')
							if len(name.keys()) == 1:
								name = name['text']
					case 'set_lore' | 'minecraft:set_lore':
						description = function['lore']
						if type(description) is list and type(desc := description[0]) is dict:
							short_desc = desc.pop('text')
							if desc == {'color': 'gray', 'italic': False}:
								description = short_desc
							else:
								desc['text'] = short_desc
					case 'set_nbt' | 'minecraft:set_nbt':
						tag = function['tag']
						new_tag, custom_model_data = pop_primitive_tag_key(tag, 'CustomModelData')
						custom_model_data = int(custom_model_data)
						disc_index = custom_model_data - CUSTOM_MODEL_DATA_ID
						if new_tag.replace(',', '').replace(' ', '') != '{HideFlags:32}':
							nbt = tag
		discs[disc_index] = {
			'id': disc_file,
			'name': name,
			'description': description
		}
		if nbt:
			discs[disc_index]['nbt'] = nbt
		sounds: dict = sounds_file.get('music_disc.'+disc_file, {'sounds': []})['sounds']
		if len(sounds) > 1:
			overrides = []
			for sound in sounds:
				overrides.append({
					'name': sound['name'].replace('murderdrones:records/', ''),
					'weight': sound.get('weight', 1)
				})
			discs[disc_index]['sounds'] = overrides
	with open(DISCS_PATH+'discs.json', 'w', encoding='UTF-8') as file:
		json.dump(discs, file, indent='\t', ensure_ascii=False)
	# print(json.dumps(discs, indent='\t', ensure_ascii=False))
