from collections import namedtuple
import uuid

import marshmallow as ma

from app.objects.interfaces.i_object import FirstClassObjectInterface
from app.objects.secondclass.c_fact import FactSchema, OriginType
from app.objects.secondclass.c_rule import RuleSchema
from app.objects.secondclass.c_relationship import RelationshipSchema
from app.utility.base_object import BaseObject


class AdjustmentSchema(ma.Schema):

    ability_id = ma.fields.String()
    trait = ma.fields.String()
    value = ma.fields.String()
    offset = ma.fields.Integer()

    @ma.post_load()
    def build_adjustment(self, data, **_):
        return Adjustment(**data)


Adjustment = namedtuple('Adjustment', 'ability_id trait value offset')


class SourceSchema(ma.Schema):

    id = ma.fields.String()
    name = ma.fields.String()
    facts = ma.fields.List(ma.fields.Nested(FactSchema))
    rules = ma.fields.List(ma.fields.Nested(RuleSchema))
    adjustments = ma.fields.List(ma.fields.Nested(AdjustmentSchema))
    relationships = ma.fields.List(ma.fields.Nested(RelationshipSchema))
    plugin = ma.fields.String(load_default=None)

    @ma.pre_load
    def fix_adjustments(self, in_data, **_):
        x = []
        raw_adjustments = in_data.pop('adjustments', {})
        if raw_adjustments and isinstance(raw_adjustments, dict):
            for ability_id, adjustments in raw_adjustments.items():
                for trait, block in adjustments.items():
                    for change in block:
                        x.append(dict(ability_id=ability_id, trait=trait, value=change.get('value'),
                                      offset=change.get('offset')))
        in_data['adjustments'] = x
        self._fix_loaded_object_origins(in_data)
        return in_data

    @ma.post_load()
    def build_source(self, data, **kwargs):
        return None if kwargs.get('partial') is True else Source(**data)

    @staticmethod
    def _fix_loaded_object_origins(input_data):
        """
        Sort through input_data's facts and relationships, and patch them to include origin and references
        :param input_data: A 'source' dictionary
        :return: input_data with updated facts/relationships (patched in place)
        """
        for y in input_data.get('facts', []):
            y['origin_type'] = OriginType.IMPORTED.name
            y['source'] = input_data['id']
        for y in input_data.get('relationships', []):
            y['source']['origin_type'] = OriginType.IMPORTED.name
            y['source']['source'] = input_data['id']
            if y.get('target'):
                y['target']['origin_type'] = OriginType.IMPORTED.name
                y['target']['source'] = input_data['id']


class Source(FirstClassObjectInterface, BaseObject):

    schema = SourceSchema()
    display_schema = SourceSchema(exclude=('adjustments',))

    @property
    def unique(self):
        return self.hash('%s' % self.id)

    def __init__(self, name='', id='', facts=(), relationships=(), rules=(), adjustments=(), plugin=''):
        super().__init__()
        self.id = id if id else str(uuid.uuid4())
        self.name = name
        self.facts = facts
        self.rules = rules
        self.adjustments = adjustments
        self.relationships = relationships
        self.plugin = plugin

    def store(self, ram):
        existing = self.retrieve(ram['sources'], self.unique)
        if not existing:
            ram['sources'].append(self)
            return self.retrieve(ram['sources'], self.unique)
        existing.update('name', self.name)
        existing.update('facts', self.facts)
        existing.update('rules', self.rules)
        existing.update('relationships', self.relationships)
        existing.update('plugin', self.plugin)
        return existing
