#
# -*- coding: utf-8 -*-
#
# This file is part of reclass (http://github.com/madduck/reclass)
#
# Copyright © 2007–14 martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#

import six
import re

class DictPath(object):
    '''
    Represents a path into a nested dictionary.

    Given a dictionary like

      d['foo']['bar'] = 42

    it can be desirable to obtain a reference to the value stored in the
    sub-levels, allowing that value to be accessed and changed. Unfortunately,
    Python provides no easy way to do this, since

      ref = d['foo']['bar']

    does become a reference to the integer 42, but that reference is
    overwritten when one assigns to it. Hence, DictPath represents the path
    into a nested dictionary, and can be "applied to" a dictionary to obtain
    and set values, using a list of keys, or a string representation using
    a delimiter (which can be escaped):

      p = DictPath(':', 'foo:bar')
      p.get_value(d)
      p.set_value(d, 43)

    This is a bit backwards, but the right way around would require support by
    the dict() type.

    The primary purpose of this class within reclass is to cater for parameter
    interpolation, so that a reference such as ${foo:bar} in a parameter value
    may be resolved in the context of the Parameter collections (a nested
    dict).

    If the value is a list, then the "key" is assumed to be and interpreted as
    an integer index:

      d = {'list': [{'one':1},{'two':2}]}
      p = DictPath(':', 'list:1:two')
      p.get_value(d)  → 2

    This heuristic is okay within reclass, because dictionary keys (parameter
    names) will always be strings. Therefore it is okay to interpret each
    component of the path as a string, unless one finds a list at the current
    level down the nested dictionary.
    '''

    def __init__(self, delim, contents=None):
        self._delim = delim
        if contents is None:
            self._parts = []
        else:
            if isinstance(contents, list):
                self._parts = contents
            elif isinstance(contents, six.string_types):
                self._parts = self._split_string(contents)
            elif isinstance(contents, tuple):
                self._parts = list(contents)
            else:
                raise TypeError('DictPath() takes string or list, '\
                                'not %s' % type(contents))

    def __repr__(self):
        return "DictPath(%r, %r)" % (self._delim, str(self))

    def __str__(self):
        return self._delim.join(str(i) for i in self._parts)

    def __eq__(self, other):
        if isinstance(other, six.string_types):
            other = DictPath(self._delim, other)

        return self._parts == other._parts \
                and self._delim == other._delim

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(str(self))

    def _get_path(self):
        return self._parts
    path = property(_get_path)

    def _get_key(self):
        if len(self._parts) == 0:
            return None
        return self._parts[-1]

    def _get_innermost_container(self, base):
        container = base
        for i in self.path[:-1]:
            if isinstance(container, (list, tuple)):
                container = container[int(i)]
            else:
                container = container[i]
        return container

    def _split_string(self, string):
        return re.split(r'(?<!\\)' + re.escape(self._delim), string)

    def _escape_string(self, string):
        return string.replace(self._delim, '\\' + self._delim)

    def has_ancestors(self):
        return len(self._parts) > 1

    def key_parts(self):
        if self.has_ancestors():
            return self._parts[:-1]
        else:
            return []

    def new_subpath(self, key):
        return DictPath(self._delim, self._parts + [key])

    def get_value(self, base):
        return self._get_innermost_container(base)[self._get_key()]

    def set_value(self, base, value):
        self._get_innermost_container(base)[self._get_key()] = value

    def drop_first(self):
        del self._parts[0]
        return self

    def is_empty(self):
        return len(self._parts) == 0

    def delete(self, base):
        del self._get_innermost_container(base)[self._get_key()]

    def add_subpath(self, key):
        self._parts.append(key)

    def is_ancestor_of(self, other):
        if len(other._parts) <= len(self._parts):
            return False
        for i in range(len(self._parts)):
            if other._parts[i] != self._parts[i]:
                return False
        return True

    def exists_in(self, container):
        item = container
        for i in self._parts:
            if isinstance(item, (dict, list)):
                if i in item:
                    if isinstance(item, dict):
                        item = item[i]
                    elif isinstance(container, list):
                        item = item[int(i)]
                else:
                    return False
            else:
                if item == self._parts[-1]:
                    return True
                else:
                    return False
        return True
