#-----------------------------------------------------------------------------
#Author: Vibhu Agarwal
#-----------------------------------------------------------------------------

from dataclasses import dataclass
from dataclasses import asdict
from dataclasses import field
from bs4 import BeautifulSoup
from pprint import pprint
import requests
import sys


@dataclass
class Spell:
	name: str
	type: str = field(init=False, repr=True, default=None)
	pronunciation: str
	description: str

@dataclass
class Enchantment:
	name: str
	type: str = field(init=False, repr=True, default=None)
	description: str

def adjust(text):
	ind = text.find('(')
	return text[:ind-1] if ind > 0 else text

def fix(text):
        text = text.replace('\n','')
        text = text.strip()
        return text

def get_spells():
	url = 'https://harrypotter.wikia.com/wiki/List_of_spells'

	try:
		#print('Creating response ...')
		response_search_page = requests.get(url)
	except:
		print('Failed to create response of search page')
		return (None, None)

	try:
		#print('Creating response ...')
		soup = BeautifulSoup(response_search_page.text,'lxml')
	except:
		print('Could not make soup from response')
		return (None, None)

	try:
		tabbertabs = soup.find_all('div',{'class':'tabbertab'})
	except:
		print('Failed to load tabbertabs')
		return (None, None)

	if len(tabbertabs) == 0:
		print('Failed to load tabbertabs')
		return (None, None)

	spells = {}
	enchantments = {}

	detail = {'name':'Legilimens',
                  'full_name':'Legilimens (Legilimency Spell)',
                  'type':'Type: Charm ',
                  'pron':'Pronunciation: Le-JIL-ih-mens',
                  'desc':'Description: Allows the caster to delve into the mind of the victim, allowing the caster to see the memories, thoughts, and emotions of the victim.'}
	for tabbertab in tabbertabs:
		for tag in tabbertab:
			if tag.name == 'h3':
				spell_name = tag.text
				if detail['name'] not in spells and detail['name'] not in enchantments:
					if 'desc' in detail:
						if 'pron' in detail:
							new_spell = Spell(detail['full_name'],
                                                                          detail['pron'],
                                                                          detail['desc'])
							if 'type' in detail:
								new_spell.type = detail['type']
							spells[detail['name']] = new_spell
						else:
							new_enchantment = Enchantment(detail['full_name'],
                                                                                      detail['desc'])
							if 'type' in detail:
								new_enchantment.type = detail['type']
							enchantments[detail['name']] = new_enchantment
					else:
						print('Not enough information about', detail['name'])
				detail = {'name':adjust(spell_name),
                                          'full_name':spell_name}
				dl_not_defined = True
			elif tag.name == 'dl' and dl_not_defined:
				dds = tag.find_all('dd')
				for dd in dds:
					property_text = fix(dd.text)
					if 'Pronunciation' in property_text and 'Unknown' not in property_text:
						detail['pron'] = property_text
					elif 'Type' in property_text:
						detail['type'] = property_text
					elif 'Description' in property_text:
						detail['desc'] = property_text
				if 'pron' in detail or 'type' in detail or 'desc' in detail:
					dl_not_defined = False

	new_spell = Spell(detail['full_name'],
                          detail['pron'],
                          detail['desc'])
	new_spell.type = detail['type']
	spells[detail['name']] = new_spell

	return (spells, enchantments)

if __name__ == '__main__':
	spells, enchantments = get_spells()
	for key in spells:
		print(key)
		print(asdict(spells[key]),'\n')
	for key in enchantments:
		print(key)
		print(asdict(enchantments[key]),'\n')
