from xml.etree import ElementTree
from parallels.core.utils.common import cached
from parallels.core.utils.plesk_utils import get_packages_xml


def get_installed_components(plesk_server):
    """Get list of components installation status in simple format

    For now only Perl and Python are supported. Extend if necessary.
    Example result: {'perl': True, 'python': False}

    :type plesk_server: parallels.core.connections.plesk_server.PleskServer
    :rtype: dict[str, bool]
    """
    components = {}

    if plesk_server.is_windows():
        packages_xml_str = get_packages_xml(plesk_server)
        packages_xml = ElementTree.fromstring(packages_xml_str)
        for elem in packages_xml.findall('type'):
            if elem.attrib.get('name') == 'script.python':
                name = 'python'
            elif elem.attrib.get('name') == 'script.perl':
                name = 'perl'
            else:
                name = None

            if name is not None:
                installed = False
                package_node = elem.find('package')
                if package_node is not None:
                    installed = package_node.attrib.get('state') != 'not_installed'

                components[name] = installed
    else:
        query_results = plesk_server.query_panel_db(
            "SELECT name FROM ServiceNodeEnvironment "
            "WHERE section = 'componentsPackages' AND name in ('mod_python', 'mod_perl') "
            "AND value != ''"
        )
        raw_components = {row["name"] for row in query_results}
        components['python'] = 'mod_python' in raw_components
        components['perl'] = 'mod_perl' in raw_components

    return components


@cached
def get_available_components(plesk_server):
    """Get list of components that are installed or can be installed

    Now works for Unix only.

    :type plesk_server: parallels.core.connections.plesk_server.PleskServer
    :rtype: set[str | unicode]
    """

    query_results = plesk_server.query_panel_db(
        "SELECT name FROM ServiceNodeEnvironment WHERE section = 'componentsPackages'"
    )
    return {row["name"] for row in query_results}
