"""
This module provides an abstraction layer over common Rust pretty printing
functionality needed by both GDB and LLDB.
"""

import re

# Type codes that indicate the kind of type as it appears in DWARF debug
# information. This code alone is not sufficient to determine the Rust type.
# For example structs, tuples, fat pointers, or enum variants will all have
# DWARF_TYPE_CODE_STRUCT.
DWARF_TYPE_CODE_STRUCT = 1
DWARF_TYPE_CODE_UNION  = 2
DWARF_TYPE_CODE_PTR    = 3
DWARF_TYPE_CODE_ARRAY  = 4
DWARF_TYPE_CODE_ENUM   = 5

# These constants specify the most specific kind of type that could be
# determined for a given value.
TYPE_KIND_UNKNOWN           = -1
TYPE_KIND_EMPTY             = 0
TYPE_KIND_SLICE             = 1
TYPE_KIND_REGULAR_STRUCT    = 2
TYPE_KIND_TUPLE             = 3
TYPE_KIND_TUPLE_STRUCT      = 4
TYPE_KIND_CSTYLE_VARIANT    = 5
TYPE_KIND_TUPLE_VARIANT     = 6
TYPE_KIND_STRUCT_VARIANT    = 7
TYPE_KIND_STR_SLICE         = 8
TYPE_KIND_STD_VEC           = 9
TYPE_KIND_STD_STRING        = 10
TYPE_KIND_REGULAR_ENUM      = 11
TYPE_KIND_COMPRESSED_ENUM   = 12
TYPE_KIND_SINGLETON_ENUM    = 13
TYPE_KIND_CSTYLE_ENUM       = 14
TYPE_KIND_PTR               = 15
TYPE_KIND_FIXED_SIZE_VEC    = 16
TYPE_KIND_REGULAR_UNION     = 17
TYPE_KIND_OS_STRING         = 18
TYPE_KIND_STD_VECDEQUE      = 19
TYPE_KIND_STD_BTREESET      = 20
TYPE_KIND_STD_BTREEMAP      = 21

ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR"

# Slice related constants
SLICE_FIELD_NAME_DATA_PTR = "data_ptr"
SLICE_FIELD_NAME_LENGTH = "length"
SLICE_FIELD_NAMES = [SLICE_FIELD_NAME_DATA_PTR, SLICE_FIELD_NAME_LENGTH]

# std::Vec<> related constants
STD_VEC_FIELD_NAME_LENGTH = "len"
STD_VEC_FIELD_NAME_BUF = "buf"
STD_VEC_FIELD_NAMES = [STD_VEC_FIELD_NAME_BUF,
                       STD_VEC_FIELD_NAME_LENGTH]

# std::collections::VecDeque<> related constants
STD_VECDEQUE_FIELD_NAME_TAIL = "tail"
STD_VECDEQUE_FIELD_NAME_HEAD = "head"
STD_VECDEQUE_FIELD_NAME_BUF = "buf"
STD_VECDEQUE_FIELD_NAMES = [STD_VECDEQUE_FIELD_NAME_TAIL,
                            STD_VECDEQUE_FIELD_NAME_HEAD,
                            STD_VECDEQUE_FIELD_NAME_BUF]

# std::collections::BTreeSet<> related constants
STD_BTREESET_FIELD_NAMES = ["map"]

# std::collections::BTreeMap<> related constants
STD_BTREEMAP_FIELD_NAMES = ["root", "length"]

# std::String related constants
STD_STRING_FIELD_NAMES = ["vec"]

# std::ffi::OsString related constants
OS_STRING_FIELD_NAMES = ["inner"]


class Type(object):
    """
    This class provides a common interface for type-oriented operations.
    Sub-classes are supposed to wrap a debugger-specific type-object and
    provide implementations for the abstract methods in this class.
    """

    def __init__(self):
        self.__type_kind = None

    def get_unqualified_type_name(self):
        """
        Implementations of this method should return the unqualified name of the
        type-object they are wrapping. Some examples:

        'int' -> 'int'
        'std::vec::Vec<std::string::String>' -> 'Vec<std::string::String>'
        '&std::option::Option<std::string::String>' -> '&std::option::Option<std::string::String>'

        As you can see, type arguments stay fully qualified.
        """
        raise NotImplementedError("Override this method")

    def get_dwarf_type_kind(self):
        """
        Implementations of this method should return the correct
        DWARF_TYPE_CODE_* value for the wrapped type-object.
        """
        raise NotImplementedError("Override this method")

    def get_fields(self):
        """
        Implementations of this method should return a list of field-objects of
        this type. For Rust-enums (i.e. with DWARF_TYPE_CODE_UNION) these field-
        objects represent the variants of the enum. Field-objects must have a
        `name` attribute that gives their name as specified in DWARF.
        """
        assert ((self.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT) or
                (self.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION))
        raise NotImplementedError("Override this method")

    def get_wrapped_value(self):
        """
        Returns the debugger-specific type-object wrapped by this object. This
        is sometimes needed for doing things like pointer-arithmetic in GDB.
        """
        raise NotImplementedError("Override this method")

    def get_type_kind(self):
        """This method returns the TYPE_KIND_* value for this type-object."""
        if self.__type_kind is None:
            dwarf_type_code = self.get_dwarf_type_kind()

            if dwarf_type_code == DWARF_TYPE_CODE_STRUCT:
                self.__type_kind = self.__classify_struct()
            elif dwarf_type_code == DWARF_TYPE_CODE_UNION:
                self.__type_kind = self.__classify_union()
            elif dwarf_type_code == DWARF_TYPE_CODE_PTR:
                self.__type_kind = TYPE_KIND_PTR
            elif dwarf_type_code == DWARF_TYPE_CODE_ARRAY:
                self.__type_kind = TYPE_KIND_FIXED_SIZE_VEC
            else:
                self.__type_kind = TYPE_KIND_UNKNOWN
        return self.__type_kind

    def __classify_struct(self):
        assert self.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT

        unqualified_type_name = self.get_unqualified_type_name()

        # STR SLICE
        if unqualified_type_name == "&str":
            return TYPE_KIND_STR_SLICE

        # REGULAR SLICE
        if (unqualified_type_name.startswith(("&[", "&mut [")) and
            unqualified_type_name.endswith("]") and
            self.__conforms_to_field_layout(SLICE_FIELD_NAMES)):
            return TYPE_KIND_SLICE

        fields = self.get_fields()
        field_count = len(fields)

        # EMPTY STRUCT
        if field_count == 0:
            return TYPE_KIND_EMPTY

        # STD VEC
        if (unqualified_type_name.startswith("Vec<") and
            self.__conforms_to_field_layout(STD_VEC_FIELD_NAMES)):
            return TYPE_KIND_STD_VEC

        # STD COLLECTION VECDEQUE
        if (unqualified_type_name.startswith("VecDeque<") and
            self.__conforms_to_field_layout(STD_VECDEQUE_FIELD_NAMES)):
            return TYPE_KIND_STD_VECDEQUE

        # STD COLLECTION BTREESET
        if (unqualified_type_name.startswith("BTreeSet<") and
                self.__conforms_to_field_layout(STD_BTREESET_FIELD_NAMES)):
            return TYPE_KIND_STD_BTREESET

        # STD COLLECTION BTREEMAP
        if (unqualified_type_name.startswith("BTreeMap<") and
                self.__conforms_to_field_layout(STD_BTREEMAP_FIELD_NAMES)):
            return TYPE_KIND_STD_BTREEMAP

        # STD STRING
        if (unqualified_type_name.startswith("String") and
            self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)):
            return TYPE_KIND_STD_STRING

        # OS STRING
        if (unqualified_type_name == "OsString" and
            self.__conforms_to_field_layout(OS_STRING_FIELD_NAMES)):
            return TYPE_KIND_OS_STRING

        # ENUM VARIANTS
        if fields[0].name == ENUM_DISR_FIELD_NAME:
            if field_count == 1:
                return TYPE_KIND_CSTYLE_VARIANT
            elif self.__all_fields_conform_to_tuple_field_naming(1):
                return TYPE_KIND_TUPLE_VARIANT
            else:
                return TYPE_KIND_STRUCT_VARIANT

        # TUPLE
        if self.__all_fields_conform_to_tuple_field_naming(0):
            if unqualified_type_name.startswith("("):
                return TYPE_KIND_TUPLE
            else:
                return TYPE_KIND_TUPLE_STRUCT

        # REGULAR STRUCT
        return TYPE_KIND_REGULAR_STRUCT


    def __classify_union(self):
        assert self.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION

        union_members = self.get_fields()
        union_member_count = len(union_members)
        if union_member_count == 0:
            return TYPE_KIND_EMPTY

        first_variant_name = union_members[0].name
        if first_variant_name is None:
            if union_member_count == 1:
                return TYPE_KIND_SINGLETON_ENUM
            else:
                return TYPE_KIND_REGULAR_ENUM
        elif first_variant_name.startswith(ENCODED_ENUM_PREFIX):
            assert union_member_count == 1
            return TYPE_KIND_COMPRESSED_ENUM
        else:
            return TYPE_KIND_REGULAR_UNION


    def __conforms_to_field_layout(self, expected_fields):
        actual_fields = self.get_fields()
        actual_field_count = len(actual_fields)

        if actual_field_count != len(expected_fields):
            return False

        for i in range(0, actual_field_count):
            if actual_fields[i].name != expected_fields[i]:
                return False

        return True

    def __all_fields_conform_to_tuple_field_naming(self, start_index):
        fields = self.get_fields()
        field_count = len(fields)

        for i in range(start_index, field_count):
            field_name = fields[i].name
            if (field_name is None) or (re.match(r"__\d+$", field_name) is None):
                return False
        return True


class Value(object):
    """
    This class provides a common interface for value-oriented operations.
    Sub-classes are supposed to wrap a debugger-specific value-object and
    provide implementations for the abstract methods in this class.
    """
    def __init__(self, ty):
        self.type = ty

    def get_child_at_index(self, index):
        """Returns the value of the field, array element or variant at the given index"""
        raise NotImplementedError("Override this method")

    def as_integer(self):
        """
        Try to convert the wrapped value into a Python integer. This should
        always succeed for values that are pointers or actual integers.
        """
        raise NotImplementedError("Override this method")

    def get_wrapped_value(self):
        """
        Returns the debugger-specific value-object wrapped by this object. This
        is sometimes needed for doing things like pointer-arithmetic in GDB.
        """
        raise NotImplementedError("Override this method")


class EncodedEnumInfo(object):
    """
    This class provides facilities for handling enum values with compressed
    encoding where a non-null field in one variant doubles as the discriminant.
    """

    def __init__(self, enum_val):
        assert enum_val.type.get_type_kind() == TYPE_KIND_COMPRESSED_ENUM
        variant_name = enum_val.type.get_fields()[0].name
        last_separator_index = variant_name.rfind("$")
        start_index = len(ENCODED_ENUM_PREFIX)
        indices_substring = variant_name[start_index:last_separator_index].split("$")
        self.__enum_val = enum_val
        self.__disr_field_indices = [int(index) for index in indices_substring]
        self.__null_variant_name = variant_name[last_separator_index + 1:]

    def is_null_variant(self):
        ty = self.__enum_val.type
        sole_variant_val = self.__enum_val.get_child_at_index(0)
        discriminant_val = sole_variant_val
        for disr_field_index in self.__disr_field_indices:
            discriminant_val = discriminant_val.get_child_at_index(disr_field_index)

        # If the discriminant field is a fat pointer we have to consider the
        # first word as the true discriminant
        if discriminant_val.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT:
            discriminant_val = discriminant_val.get_child_at_index(0)

        return discriminant_val.as_integer() == 0

    def get_non_null_variant_val(self):
        return self.__enum_val.get_child_at_index(0)

    def get_null_variant_name(self):
        return self.__null_variant_name


def get_discriminant_value_as_integer(enum_val):
    assert enum_val.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION
    # we can take any variant here because the discriminant has to be the same
    # for all of them.
    variant_val = enum_val.get_child_at_index(0)
    disr_val = variant_val.get_child_at_index(0)
    return disr_val.as_integer()


def extract_length_ptr_and_cap_from_std_vec(vec_val):
    assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VEC
    length_field_index = STD_VEC_FIELD_NAMES.index(STD_VEC_FIELD_NAME_LENGTH)
    buf_field_index = STD_VEC_FIELD_NAMES.index(STD_VEC_FIELD_NAME_BUF)

    length = vec_val.get_child_at_index(length_field_index).as_integer()
    buf = vec_val.get_child_at_index(buf_field_index)

    vec_ptr_val = buf.get_child_at_index(0)
    capacity = buf.get_child_at_index(1).as_integer()
    data_ptr = vec_ptr_val.get_child_at_index(0)
    assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
    return (length, data_ptr, capacity)


def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val):
    assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VECDEQUE
    tail_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_TAIL)
    head_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_HEAD)
    buf_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_BUF)

    tail = vec_val.get_child_at_index(tail_field_index).as_integer()
    head = vec_val.get_child_at_index(head_field_index).as_integer()
    buf = vec_val.get_child_at_index(buf_field_index)

    vec_ptr_val = buf.get_child_at_index(0)
    capacity = buf.get_child_at_index(1).as_integer()
    data_ptr = vec_ptr_val.get_child_at_index(0)
    assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
    return (tail, head, data_ptr, capacity)

def extract_length_and_ptr_from_slice(slice_val):
    assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or
            slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE)

    length_field_index = SLICE_FIELD_NAMES.index(SLICE_FIELD_NAME_LENGTH)
    ptr_field_index = SLICE_FIELD_NAMES.index(SLICE_FIELD_NAME_DATA_PTR)

    length = slice_val.get_child_at_index(length_field_index).as_integer()
    data_ptr = slice_val.get_child_at_index(ptr_field_index)

    assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
    return (length, data_ptr)

UNQUALIFIED_TYPE_MARKERS = frozenset(["(", "[", "&", "*"])

def extract_type_name(qualified_type_name):
    """Extracts the type name from a fully qualified path"""
    if qualified_type_name[0] in UNQUALIFIED_TYPE_MARKERS:
        return qualified_type_name

    end_of_search = qualified_type_name.find("<")
    if end_of_search < 0:
        end_of_search = len(qualified_type_name)

    index = qualified_type_name.rfind("::", 0, end_of_search)
    if index < 0:
        return qualified_type_name
    else:
        return qualified_type_name[index + 2:]

try:
    compat_str = unicode  # Python 2
except NameError:
    compat_str = str
