#
# -*- coding: utf-8 -*-
#
# This file is part of reclass
#

from parser import Parser
from dictitem import DictItem
from listitem import ListItem
from scaitem import ScaItem
from reclass.errors import ResolveError

class Value(object):

    _parser = Parser()

    def __init__(self, value, settings, uri):
        self._settings = settings
        self._uri = uri
        if isinstance(value, str):
            self._item = self._parser.parse(value, self._settings)
        elif isinstance(value, list):
            self._item = ListItem(value, self._settings)
        elif isinstance(value, dict):
            self._item = DictItem(value, self._settings)
        else:
            self._item = ScaItem(value, self._settings)

    def is_container(self):
        return self._item.is_container()

    def allRefs(self):
        return self._item.allRefs()

    def has_references(self):
        return self._item.has_references()

    def has_inv_query(self):
        return self._item.has_inv_query()

    def is_complex(self):
        return self._item.is_complex()

    def get_references(self):
        return self._item.get_references()

    def assembleRefs(self, context):
        if self._item.has_references():
            self._item.assembleRefs(context)

    def render(self, context, inventory):
        try:
            return self._item.render(context, inventory)
        except ResolveError as e:
            e.uri = self._uri
            raise e

    def contents(self):
        return self._item.contents()

    def merge_over(self, value):
        self._item = self._item.merge_over(value._item)
        return self

    def __repr__(self):
        return 'Value(%r)' % self._item
