# -*- coding: utf-8 -*-
from collections import namedtuple
from collective.easyform.migration.fields import append_field
from collective.easyform.migration.fields import append_list_node
from collective.easyform.migration.fields import append_node
from collective.easyform.migration.fields import set_attribute
from collective.easyform.migration.fields import to_text
from lxml import etree
from Products.PloneFormGen.content.actionAdapter import FormActionAdapter

import logging

try:
  from collective.easyform.interfaces.mailer import default_mail_body
except ImportError:
  from collective.easyform.config import MAIL_BODY_DEFAULT
  def default_mail_body():
    return MAIL_BODY_DEFAULT


logger = logging.getLogger('collective.easyform.migration')


NAMESPACES = {
    'easyform': 'http://namespaces.plone.org/supermodel/easyform',
    'form': 'http://namespaces.plone.org/supermodel/form',
}


def append_body_pt(field, name, value):
    node = append_node(field, name, value)
    # Replace mailer page template with the default one from easyform as it's
    # unlikely that the PFG template would work.
    node.text = default_mail_body()


Type = namedtuple('Type', ['name', 'handler'])
Property = namedtuple('Property', ['name', 'handler'])


TYPES_MAPPING = {
    'FormMailerAdapter': Type('collective.easyform.actions.Mailer', append_field),
    'FormSaveDataAdapter': Type('collective.easyform.actions.SaveData', append_field),
    'FormCustomScriptAdapter': Type('collective.easyform.actions.CustomScript', append_field),
}

PROPERTIES_MAPPING = {
    'additional_headers': Property('additional_headers', append_node),
    'bcc_recipients': Property('bcc_recipients', append_node),
    'bccOverride': Property('bccOverride', append_node),
    'body_footer': Property('body_footer', append_node),
    'body_post': Property('body_post', append_node),
    'body_pre': Property('body_pre', append_node),
    'body_pt': Property('body_pt', append_body_pt),
    'body_type': Property('body_type', append_node),
    'cc_recipients': Property('cc_recipients', append_node),
    'ccOverride': Property('ccOverride', append_node),
    'description': Property('description', append_node),
    'execCondition': Property('easyform:execCondition', set_attribute),
    'msg_subject': Property('msg_subject', append_node),
    'recipient_email': Property('recipient_email', append_node),
    'recipient_name': Property('recipient_name', append_node),
    'recipientOverride': Property('recipientOverride', append_node),
    'replyto_field': Property('replyto_field', append_node),
    'senderOverride': Property('senderOverride', append_node),
    'showAll': Property('showAll', append_node),
    'showFields': Property('showFields', append_list_node),
    'subject_field': Property('subject_field', append_node),
    'subjectOverride': Property('subjectOverride', append_node),
    'title': Property('title', append_node),
    'to_field': Property('to_field', append_node),
    'xinfo_headers': Property('xinfo_headers', append_node),
    'ExtraData': Property('ExtraData', append_list_node),
    'DownloadFormat': Property('DownloadFormat', append_node),
    'UseColumnNames': Property('UseColumnNames', append_node),
    'SavedFormInput': Property('SavedFormInput', append_node),
    'ProxyRole': Property('ProxyRole', append_node),
    'ScriptBody': Property('ScriptBody', append_node),
}


def pfg_actions(context):
    actions = []
    for obj in context.objectValues():
        if not isinstance(obj, FormActionAdapter):
            continue
        id_ = obj.getId()
        props = {}
        props['_portal_type'] = obj.portal_type
        for field in obj.Schema().fields():
            name = field.getName()
            accessor = field.getEditAccessor(obj)
            props[name] = accessor()
        actions.append((id_, props))
    return actions


def actions_model(ploneformgen):
    """Create an actions xml model from a PloneFormGen instance."""
    parser = etree.XMLParser(remove_blank_text=True)
    model = etree.fromstring(ACTIONS_MODEL, parser)
    schema = model.find(
        '{http://namespaces.plone.org/supermodel/schema}schema')

    for actionname, properties in pfg_actions(ploneformgen):
        type_ = TYPES_MAPPING.get(properties['_portal_type'])
        if type_ is None:
            # ploneformgen has been renamed with _MIGRATION_ suffix
            # hence, we remove 11 chars
            pfgpath = "/".join(ploneformgen.getPhysicalPath())[:-11]
            logger.warning(
                "Ignoring field '%s' of type '%s' of form '%s.",
                actionname, properties['_portal_type'], pfgpath)
            continue

        field = type_.handler(schema, type_.name, actionname, properties)

        for name, value in properties.items():
            prop = PROPERTIES_MAPPING.get(name)
            if prop is None:
                continue

            value = to_text(value)

            prop.handler(field, prop.name, value)

    return etree.tostring(model, pretty_print=True)


ACTIONS_MODEL = b"""
<model xmlns="http://namespaces.plone.org/supermodel/schema">
  <schema></schema>
</model>
"""
