# -*- coding: utf-8 -*-
# OpenFisca -- A versatile microsimulation software
# By: OpenFisca Team <contact@openfisca.fr>
#
# Copyright (C) 2011, 2012, 2013, 2014 OpenFisca Team
# https://github.com/openfisca
#
# This file is part of OpenFisca.
#
# OpenFisca is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# OpenFisca is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""Handle legislative parameters in XML format (and convert then to JSON)."""
import collections
import logging
import itertools
import datetime
from openfisca_core import conv
from datetime import datetime as dt
#legislation_json_key_by_xml_tag = dict(
#    ASSIETTE = 'base',  # "base" is singular, because a slice has only one base.
#    BAREME = 'scales',
#    CODE = 'parameters',
#    NODE = 'nodes',
#    SEUIL= 'threshold',  # "threshold" is singular, because a slice has only one base.
#    TAUX = 'rate',  # "rate" is singular, because a slice has only one base.
#    TRANCHE = 'slices',
#    VALUE = 'values',
#    )
log = logging.getLogger(__name__)
json_unit_by_xml_json_type = dict(
    age = u'year',
    days = u'day',
    hours = u'hour',
    monetary = u'currency',
    months = u'month',
    )
N_ = lambda message: message
xml_json_formats = (
    'bool',
    'float',
    'integer',
    'percent',
    'date',
    )
def make_validate_values_xml_json_dates(require_consecutive_dates = False):
    def validate_values_xml_json_dates(values_xml_json, state = None):
        if not values_xml_json:
            return values_xml_json, None
        if state is None:
            state = conv.default_state
        errors = {}
        for index, value_xml_json in enumerate(values_xml_json):
            if value_xml_json['deb'] > value_xml_json['fin']:
                errors[index] = dict(fin = state._(u"Last date must be greater than first date"))
        sorted_values_xml_json = sorted(values_xml_json, key = lambda value_xml_json: value_xml_json['deb'],
            reverse = True)
        next_value_xml_json = sorted_values_xml_json[0]
        for index, value_xml_json in enumerate(itertools.islice(sorted_values_xml_json, 1, None)):
            next_date_str = (datetime.date(*(int(fragment) for fragment in value_xml_json['fin'].split('-')))
                + datetime.timedelta(days = 1)).isoformat()
            if require_consecutive_dates and next_date_str < next_value_xml_json['deb']:
                errors.setdefault(index, {})['deb'] = state._(u"Dates of values are not consecutive")
            elif next_date_str > next_value_xml_json['deb']:
                errors.setdefault(index, {})['deb'] = state._(u"Dates of values overlap")
            next_value_xml_json = value_xml_json
        return sorted_values_xml_json, errors or None
    return validate_values_xml_json_dates
def translate_xml_element_to_json_item(xml_element):
    json_element = collections.OrderedDict()
    text = xml_element.text
    if text is not None:
        text = text.strip().strip('#').strip() or None
        if text is not None:
            json_element['text'] = text
    json_element.update(xml_element.attrib)
    for xml_child in xml_element:
        json_child_key, json_child = translate_xml_element_to_json_item(xml_child)
        json_element.setdefault(json_child_key, []).append(json_child)
    tail = xml_element.tail
    if tail is not None:
        tail = tail.strip().strip('#').strip() or None
        if tail is not None:
            json_element['tail'] = tail
    return xml_element.tag, json_element
def transform_node_xml_json_to_json(node_xml_json, root = True):
    comments = []
    node_json = collections.OrderedDict()
    if root:
        node_json['@context'] = u'http://openfisca.fr/contexts/legislation.jsonld'
    node_json['@type'] = 'Node'
    child_json_by_code = {}
    for key, value in node_xml_json.iteritems():
        if key == 'BAREME':
            for child_xml_json in value:
                child_code, child_json = transform_scale_xml_json_to_json(child_xml_json)
                child_json_by_code[child_code] = child_json
        elif key == 'VALBYTRANCHES':
            for child_xml_json in value:
                child_code, child_json = transform_generation_xml_json_to_json(child_xml_json)
                child_json_by_code[child_code] = child_json
        elif key == 'CODE':
            for child_xml_json in value:
                child_code, child_json = transform_parameter_xml_json_to_json(child_xml_json)
                child_json_by_code[child_code] = child_json
        elif key == 'code':
            pass
        elif key == 'deb':
            node_json['from'] = value
        elif key == 'fin':
            node_json['to'] = value
        elif key == 'NODE':
            for child_xml_json in value:
                child_code, child_json = transform_node_xml_json_to_json(child_xml_json, root = False)
                child_json_by_code[child_code] = child_json
        elif key in ('tail', 'text'):
            comments.append(value)
        else:
            node_json[key] = value
    node_json['children'] = collections.OrderedDict(sorted(child_json_by_code.iteritems()))
    if comments:
        node_json['comment'] = u'\n\n'.join(comments)
    return node_xml_json['code'], node_json
def transform_parameter_xml_json_to_json(parameter_xml_json):
    comments = []
    parameter_json = collections.OrderedDict()
    parameter_json['@type'] = 'Parameter'
    xml_json_value_to_json_transformer = float
    for key, value in parameter_xml_json.iteritems():
        if key in ('code', 'taille'):
            pass
        elif key == 'format':
            parameter_json[key] = dict(
                bool = u'boolean',
                percent = u'rate',
                date = u'date',
                ).get(value, value)
            if value == 'bool':
                xml_json_value_to_json_transformer = lambda xml_json_value: bool(int(xml_json_value))
            elif value == 'integer':
                xml_json_value_to_json_transformer = int
        elif key in ('tail', 'text'):
            comments.append(value)
        elif key == 'type':
            parameter_json['unit'] = json_unit_by_xml_json_type.get(value, value)
        elif key == 'VALUE':
            if 'format' in parameter_xml_json:
                if parameter_xml_json['format'] ==  'date':
                    format = 'date'
                elif parameter_xml_json['format'] ==  'integer':
                    format = int
                elif parameter_xml_json['format'] ==  'percent':
                    format = float
                else:
                    format = eval(parameter_xml_json['format'])
            else:
                format = float
            parameter_json['values'] = [ transform_value_xml_json_to_json(item, format)
                for item in value
                ]
        else:
            parameter_json[key] = value
    if comments:
        parameter_json['comment'] = u'\n\n'.join(comments)
    return parameter_xml_json['code'], parameter_json
def transform_scale_xml_json_to_json(scale_xml_json):
    comments = []
    scale_json = collections.OrderedDict()
    scale_json['@type'] = 'Scale'
    for key, value in scale_xml_json.iteritems():
        if key == 'code':
            pass
        elif key in ('tail', 'text'):
            comments.append(value)
        elif key == 'TRANCHE':
            scale_json['slices'] = [
                transform_slice_xml_json_to_json(item)
                for item in value
                ]
        elif key == 'type':
            scale_json['unit'] = json_unit_by_xml_json_type.get(value, value)
        else:
            scale_json[key] = value
    if comments:
        scale_json['comment'] = u'\n\n'.join(comments)
    return scale_xml_json['code'], scale_json
def transform_generation_xml_json_to_json(generation_xml_json):
    # Note: update with OF ?
    comments = []
    generation_json = collections.OrderedDict()
    generation_json['@type'] = 'Generation'
    for key, value in generation_xml_json.iteritems():
        if key == 'code':
            pass
        elif key in ('tail', 'text'):
            comments.append(value)
        elif key == 'VARCONTROL':
            generation_json['control'] = [
                transform_value_xml_json_to_json(item, str)
                for item in value[0]['CONTROL']
                ]
        elif key == 'TRANCHE':
            generation_json['slices'] = [
                transform_slice2_xml_json_to_json(item)
                for item in value
                ]
        elif key == 'type':
            generation_json['unit'] = json_unit_by_xml_json_type.get(value, value)
        else:
            generation_json[key] = value
    if comments:
        generation_json['comment'] = u'\n\n'.join(comments)
    return generation_xml_json['code'], generation_json
def transform_slice2_xml_json_to_json(slice_xml_json):
    comments = []
    slice_json = collections.OrderedDict()
    for key, value in slice_xml_json.iteritems():
        if key == 'code':
            pass
        elif key == 'SEUIL':
            slice_json['threshold'] = transform_values_holder_xml_json_to_json(value[0], format ='date')
        elif key in ('tail', 'text'):
            comments.append(value)
        elif key == 'VALEUR':
            slice_json['valeur'] = transform_values_holder_xml_json_to_json(value[0])
        else:
            slice_json[key] = value
    if comments:
        slice_json['comment'] = u'\n\n'.join(comments)
    return slice_json
def transform_slice_xml_json_to_json(slice_xml_json):
    comments = []
    slice_json = collections.OrderedDict()
    for key, value in slice_xml_json.iteritems():
        if key == 'ASSIETTE':
            slice_json['base'] = transform_values_holder_xml_json_to_json(value[0])
        elif key == 'code':
            pass
        elif key == 'SEUIL':
            slice_json['threshold'] = transform_values_holder_xml_json_to_json(value[0])
        elif key in ('tail', 'text'):
            comments.append(value)


Answer:         elif key == 'TAUX':