from parallels.core.utils.base64_utils import base64_decode


class ApsApplication(object):
    def __init__(self, node):
        """
        :type node: xml.etree.ElementTree.Element
        """
        self._node = node

    def get_public_urls(self):
        """Get public (available to end-user) application's URLs

        Returns list, each item is a tuple (
            protocol='http'|'https',
            relative_url, relative to site's root, for example 'forum/phpBB'
        )
        """
        public_urls = []

        # Old APS, Plesk 9.x
        params = dict(self.params)
        application_url = params.get('application_url')
        application_protocol = params.get('p:ssl_prefix')
        if application_protocol is not None and application_url is not None:
            public_urls.append((application_protocol, application_url))

        # New APS, Plesk 11.x
        install_dir_node = self._node.find('sapp-installdir')
        if install_dir_node is not None:
            if install_dir_node.find('sapp-ssl') is not None:
                protocol = 'https'
            else:
                protocol = 'http'

            prefix = install_dir_node.findtext('sapp-prefix')

            if prefix is not None:
                public_urls.append((
                    protocol, prefix
                ))

        return list(set(public_urls))

    @property
    def name(self):
        """
        :rtype: str | unicode
        """
        return self._node.findtext('sapp-spec/sapp-name')

    @property
    def version(self):
        """
        :rtype: str | unicode
        """
        return self._node.findtext('sapp-spec/sapp-version')

    @property
    def release(self):
        """
        :rtype: str | unicode
        """
        return self._node.findtext('sapp-spec/sapp-release')

    @property
    def params(self):
        """
        :rtype: tuple[str | unicode, str | unicode]
        """

        params = []

        def decode_node_text(node):
            if node.text is None:
                return None
            else:
                return base64_decode(node.text)

        for param_node in self._node.findall('sapp-param'):
            name_node = param_node.find('sapp-param-name')
            value_node = param_node.find('sapp-param-value')
            if name_node is None:
                continue
            if value_node is None:
                continue
            if name_node.attrib.get('encoding') != 'base64':
                continue
            if value_node.attrib.get('encoding') != 'base64':
                continue

            params.append((
                decode_node_text(name_node),
                decode_node_text(value_node)
            ))
        return params

    @property
    def sapp_apsc(self):
        """
        :type: str | unicode | None
        """
        return self._node.findtext('sapp-apsc')

    @sapp_apsc.setter
    def sapp_apsc(self, value):
        """
        :type value: str | unicode
        :rtype: None
        :raises: NotImplementedError
        """
        sapp_apsc_node = self._node.find('sapp-apsc')
        if sapp_apsc_node is None:
            raise NotImplementedError()
        sapp_apsc_node.text = value
