# -*- coding: utf-8 -*-
"""Transform input to geodis compatible xml."""
from jinja2 import Environment, PackageLoader
from roulier.codec import Encoder
from roulier.exception import InvalidApiInput
from .geodis_common_ws import GEODIS_INFOS


GEODIS_ACTIONS = GEODIS_INFOS.keys()


class GeodisEncoderWs(Encoder):
    """Transform input to geodis compatible xml."""

    def get_api(self, action):
        """Get Api object based on action.

        raise if action is not known"""
        if not (action in GEODIS_ACTIONS):
            raise InvalidApiInput(
                'action %s not in %s' % (
                    action, ', '.join(GEODIS_INFOS)))

        return GEODIS_INFOS[action]['api']()

    def encode(self, api_input, action):
        """Transform input to geodis compatible xml."""
        api = self.get_api(action)
        if not api.validate(api_input):
            raise InvalidApiInput(
                'Input error : %s' % api.errors(api_input))
        env = Environment(
            loader=PackageLoader('roulier', '/carriers/geodis/templates'),
            extensions=['jinja2.ext.with_', 'jinja2.ext.autoescape'],
            autoescape=True)
        template = env.get_template("geodis_%s.xml" % action)

        data = api.normalize(api_input)
        infos = {
            'xmlns': GEODIS_INFOS[action]['xmlns'],
            'url': (
                data['service']['is_test'] and
                GEODIS_INFOS[action]['endpoint_test'] or
                GEODIS_INFOS[action]['endpoint']),
            'action': action,
        }

        def request_impression_etiquette():
            infos["output_format"] = api_input['service']['labelFormat'],
            data['service']['labelFormat'] = self.lookup_label_format(
                data['service']['labelFormat'])
            data['service']['shippingDate'] = (
                data['service']['shippingDate'].replace('/', ''))
            data['from_address']['departement'] = (
                data['from_address']['zip'][:2])
            return {
                "body": template.render(
                    service=data['service'],
                    parcels=data['parcels'],
                    sender_address=data['from_address'],
                    receiver_address=data['to_address'],
                    xmlns=infos['xmlns'],
                ),
                "headers": data['auth'],
                "infos": infos,
            }

        def request_find_localite():
            return {
                "body": template.render(
                    receiver_address=data['to_address'],
                    xmlns=infos['xmlns'],
                ),
                "headers": data['auth'],
                "infos": infos,
            }

        if action == 'demandeImpressionEtiquette':
            return request_impression_etiquette()
        elif action == 'findLocalite':
            return request_find_localite()

    def api(self, action='demandeImpressionEtiquette'):
        """Provide a dict prefilled with default values."""
        return self.get_api(action).api_values()

    def lookup_label_format(self, label_format="ZPL"):
        """Get a Geodis compatible format of label.

        args:
            label_format: (str) ZPL or PDF
        return
            a value taken in GEODIS_LABEL_FORMAT
        """
        lookup = {
            'ZPL': 'Z',
            'PDF': 'P',
            'HTML': 'H',
            'XML': 'X',
            'EPL2': 'E',
            'Z': 'Z',
            'P': 'P',
            'H': 'H',
            'X': 'X',
            'E': 'E',
        }
        return lookup.get(label_format.upper(), 'Z')
