from __future__ import absolute_import

from xml.etree import ElementTree

from parallels.core import messages
from parallels.core.logging import BleepingLogger, get_logger
from parallels.core.utils.clean_logging import clean_xml
from parallels.core.utils.common.xml import xml_to_string_pretty
from parallels.core.utils.config_utils import get_option
from parallels.core.utils.http_client import perform_http_request_response_text
from plesk_migrator.compatibility.utils import stringio


class HttpXmlClient(object):
    def __init__(self, url, host=None):
        log_context_length = get_option('log-message-context-length', 0)
        self.logger = BleepingLogger(
            get_logger(__name__), xml_serializer=xml_to_string_pretty,
            context_length=log_context_length
        )
        self.url = url
        self.host = host
        
    def send_raw(self, data, extra=None):
        """Send raw string to XML API."""
        headers = self._get_http_headers(data, extra)
        return perform_http_request_response_text(
            self.url, data, headers, hostname=self.host, verify_certificates=False
        )

    def send_xml(self, xml, extra=None):
        """Serialize XML object and send an API request."""
        with self.logger.debug_level_context(messages.DEBUG_API_REQUEST, target_url=self.url):
            self.logger.fdebug(messages.DEBUG_API_REQUEST_XML, xml=xml)
            request = xml_to_string_pretty(xml)
            response = self.send_raw(request, extra)
            self.logger.fdebug(messages.DEBUG_API_RESPONSE, response=clean_xml(response))
            return self._parse_xml(response)

    @staticmethod
    def _parse_xml(response):
        tree = ElementTree.ElementTree()
        tree.parse(stringio(response, is_unicode=False))
        return tree

    def _get_http_headers(self, data, extra=None):
        return {
            'Content-Type': 'text/xml',
            'Pragma': 'no-cache',
        }
