from .holiday_state import HolidayState
from libtad.datatypes.time import TADTime
from libtad.datatypes.places import Country
import xml.etree.ElementTree as ET
from urllib.parse import urlparse, ParseResult
from typing import List, Dict

class Holiday:
    '''
    A class used for holidays.
    
    ...

    Attributes
    ----------
    id : int
        Identifier for the holiday definition. Please note that this id
        is not unique, not even with a single year – the same holiday
        event may be returned multiple time because it is observed on a
        different day, or because it is scheduled in a different calendar
        (Hebrew or Muslim calendar) and happens multiple times within a
        Gregorian year. Use the Uid field for purposes where you need a
        unique identifier.
    uid : str
        Id for the shown holiday instance. The id is designed to be unique
        across all holiday instances generated by the libtad.com API
        services and respects different calendars and other reasons that
        may cause events to occurs multiple times within one Gregorian year.

        Example: 0007d600000007db
    name : str
        Holiday/Observance name.
    date : TADTime
        Date/time of the holiday instance. Most holidays do have a specific
        time – in this case the time components will be skipped. Some
        special events like equinoxes and solstices include the exact time
        of the event as well, in this case the timestamp will be in local
        time zone (including time zone data) (countries with multiple
        timezones: local time in capital city).            
    url : ParseResult
        Further information about the specific holiday. The URL points to
        the libtad.com web page.

        Example: http://www.timeanddate.com/holidays/us/new-year-day
    country : Country
        Country of the holiday instance.
    locations : str
        Summary of locations where this holiday instance is valid. Element is
        only present if the holiday instance does not affect the whole country.
    states : list of HolidayState
        States/subdivisions that are affected by this holiday instance. This
        element is only present if the holiday instance is not valid in the
        whole country.
    oneliner : str
        A short description of the holiday instance.
    types : list of str
        Classification of the holiday. Most days have only one classification,
        bust some have multiple types associated. This happens e.g. in
        conjunction with religious days that also are flag days.

        Example: National Holiday
    '''

    def __init__(self, node: ET.Element):
        self.id: int = -1
        self.uid: str = ""
        self.urlid: str = ""
        self.name: Dict[str] = {}
        self.date: TADTime = None
        self.url: ParseResult = None
        self.country: Country = None
        self.locations: str = ""
        self.states: List[HolidayState] = []
        self.oneliner: Dict[str] = {}
        self.types: List[str] = []

        ID = node.get("id")       
        url = node.get("url")
        urlid = node.get("urlid")
        name = node.find("name")
        locations = node.find("locations")
        uid = node.find("uid")
        country = node.find("country")
        oneliner = node.find("oneliner")
        types = node.find("types")
        states = node.find("states")
        date = node.find("date")

        if ID:
            self.id = int(ID)

        if url:
            self.url = urlparse(url)

        if urlid:
            self.urlid = urlid

        if uid is not None:
            self.uid = uid.text
        else:
            uid = node.get("uid")
            if uid:
                self.uid = uid

        if country is not None:
            self.country = Country(country)

        if oneliner is not None:
            for oneliner_node in oneliner:
                if oneliner_node is None:
                    continue
                oneliner_lang = oneliner_node.get("lang")
                oneliner_text = oneliner_node.text
                if oneliner_lang is not None and oneliner_text is not None:
                    self.oneliner[oneliner_lang] = oneliner_text

        if date is not None:
            self.date = TADTime(date)

        if name is not None:
            for name_node in name:
                if name_node is None:
                    continue
                name_lang = name_node.get("lang")
                name_text = name_node.text
                if name_lang is not None and name_text is not None:
                    self.name[name_lang] = name_text

        if locations is not None:
            self.locations = locations.text

        if types is not None:
            for t in types:
                self.types.append(t.text)

        if states is not None:
            for s in states:
                self.states.append(HolidayState(s))

