# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from copy import deepcopy


from ...utils.console import puts, Colored, indent


# We are inheriting the primitive types in order to add the ability to set
# an attribute (_locator) on them.

class LocatableString(unicode):
    pass


class LocatableInt(int):
    pass


class LocatableFloat(float):
    pass


def wrap(value):
    if isinstance(value, basestring):
        return True, LocatableString(value)
    elif isinstance(value, int) and \
            not isinstance(value, bool):  # Note: bool counts as int in Python!
        return True, LocatableInt(value)
    elif isinstance(value, float):
        return True, LocatableFloat(value)
    return False, value


class Locator(object):
    """
    Stores location information (line and column numbers) for agnostic raw data.
    """
    def __init__(self, location, line, column, children=None):
        self.location = location
        self.line = line
        self.column = column
        self.children = children

    def get_child(self, *names):
        if (not names) or (not isinstance(self.children, dict)):
            return self
        name = names[0]
        if name not in self.children:
            return self
        child = self.children[name]
        return child.get_child(names[1:])

    def link(self, raw, path=None):
        if hasattr(raw, '_locator'):
            # This can happen when we use anchors
            return

        try:
            setattr(raw, '_locator', self)
        except AttributeError:
            return

        if isinstance(raw, list):
            for i, raw_element in enumerate(raw):
                wrapped, raw_element = wrap(raw_element)
                if wrapped:
                    raw[i] = raw_element
                child_path = '%s.%d' % (path, i) if path else str(i)
                try:
                    self.children[i].link(raw_element, child_path)
                except KeyError:
                    raise ValueError('location map does not match agnostic raw data: %s' %
                                     child_path)
        elif isinstance(raw, dict):
            for k, raw_element in raw.iteritems():
                wrapped, raw_element = wrap(raw_element)
                if wrapped:
                    raw[k] = raw_element
                child_path = '%s.%s' % (path, k) if path else k
                try:
                    self.children[k].link(raw_element, child_path)
                except KeyError:
                    raise ValueError('location map does not match agnostic raw data: %s' %
                                     child_path)

    def merge(self, locator):
        if isinstance(self.children, dict) and isinstance(locator.children, dict):
            for k, loc in locator.children.iteritems():
                if k in self.children:
                    self.children[k].merge(loc)
                else:
                    self.children[k] = loc

    def dump(self, key=None):
        if key:
            puts('%s "%s":%d:%d' %
                 (Colored.red(key), Colored.blue(self.location), self.line, self.column))
        else:
            puts('"%s":%d:%d' % (Colored.blue(self.location), self.line, self.column))
        if isinstance(self.children, list):
            with indent(2):
                for loc in self.children:
                    loc.dump()
        elif isinstance(self.children, dict):
            with indent(2):
                for k, loc in self.children.iteritems():
                    loc.dump(k)

    def __str__(self):
        # Should be in same format as Issue.locator_as_str
        return '"%s":%d:%d' % (self.location, self.line, self.column)


def deepcopy_with_locators(value):
    """
    Like :func:`deepcopy`, but also copies over locators.
    """

    res = deepcopy(value)
    copy_locators(res, value)
    return res


def copy_locators(target, source):
    """
    Copies over ``_locator`` for all elements, recursively.

    Assumes that target and source have exactly the same list/dict structure.
    """

    locator = getattr(source, '_locator', None)
    if locator is not None:
        try:
            setattr(target, '_locator', locator)
        except AttributeError:
            pass

    if isinstance(target, list) and isinstance(source, list):
        for i, _ in enumerate(target):
            copy_locators(target[i], source[i])
    elif isinstance(target, dict) and isinstance(source, dict):
        for k, v in target.items():
            copy_locators(v, source[k])
