from typing import Tuple, List
from pathlib import Path

from .errors import HyperdentParserError
from .definitions import Order, Element, Tooth
from .utils import parse_document, get_text

FORMAT_NAME = 'hyperdent'

def is_supported(file_path: Path) -> bool:
    '''
    Is the given file path a supported hyperdent project?

    Parameters
    ----------
    file_path : Path
        The file path to check.

    Returns
    -------
    bool
        True if the file path is a supported hyperdent project, False otherwise.
    '''
    return next(file_path.glob('*.hdpp'), False)

def parse(project_path: Path) -> Tuple[List[Path], Order]:
    '''
    Parse a project consisting of hdpp files and return an `Order` object.

    Parameters
    ----------
    project_path : Path
        The path to the exocad project directory.

    Returns
    -------
    files : [Path]
        A list of all hdpp files within the folder.
    order : Order
        The order object containing the elements defined in the hdpp files.
    '''
    if not is_supported(project_path):
        raise HyperdentParserError(f'Unsupported hyperdent project: {project_path}')
    
    hdpp_files = project_path.glob('*.hdpp')
    files = []
    elements = []
    while hdp_file := next(hdpp_files, False):
        files.append(hdp_file)
        
        hdpp_doc = parse_document(hdp_file.open('rb'))
        root = hdpp_doc.getroot()

        element_material = get_text(root.find('partdata'), 'material')
        
        xml_teeth = root.findall('teeth/tooth')
        teeth = []
        for xml_tooth in xml_teeth:
            tooth_type = xml_tooth.get('type')
            tooth_number = get_text(xml_tooth, 'tno')
            implant_system = None

            implant_system_node = xml_tooth.find('implantconnect')
            if implant_system_node is not None:
                implant_system = get_text(implant_system_node, 'system')

            tooth = Tooth(fdi=tooth_number, color=None, type=tooth_type,
                    is_anatomical=False, implant_type=None, implant_system=implant_system)
            teeth.append(tooth)

        element = Element(file_name=hdp_file.with_suffix('.stl').name, material=element_material, color=None, height=0.0,
                is_screw_retained=False, type=None, teeth=teeth)
        elements.append(element)
        
    return files, Order(format=FORMAT_NAME, project=None, patient=None, comment=None,
        practice_id=None, elements=elements, models=[], scan_files=[], loaded_scene_file=None)