# DExTer : Debugging Experience Tester
# ~~~~~~   ~         ~~         ~   ~~
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from collections import namedtuple
from ctypes import *
from functools import partial

from .utils import *

Symbol = namedtuple("Symbol", ["num", "name", "type", "value"])


class IDebugSymbolGroup2(Structure):
    pass


class IDebugSymbolGroup2Vtbl(Structure):
    wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbolGroup2))
    ids_getnumbersymbols = wrp(c_ulong_p)
    ids_getsymbolname = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
    ids_getsymboltypename = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
    ids_getsymbolvaluetext = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
    _fields_ = [
        ("QueryInterface", c_void_p),
        ("AddRef", c_void_p),
        ("Release", c_void_p),
        ("GetNumberSymbols", ids_getnumbersymbols),
        ("AddSymbol", c_void_p),
        ("RemoveSymbolByName", c_void_p),
        ("RemoveSymbolByIndex", c_void_p),
        ("GetSymbolName", ids_getsymbolname),
        ("GetSymbolParameters", c_void_p),
        ("ExpandSymbol", c_void_p),
        ("OutputSymbols", c_void_p),
        ("WriteSymbol", c_void_p),
        ("OutputAsType", c_void_p),
        ("AddSymbolWide", c_void_p),
        ("RemoveSymbolByNameWide", c_void_p),
        ("GetSymbolNameWide", c_void_p),
        ("WritesymbolWide", c_void_p),
        ("OutputAsTypeWide", c_void_p),
        ("GetSymbolTypeName", ids_getsymboltypename),
        ("GetSymbolTypeNameWide", c_void_p),
        ("GetSymbolSize", c_void_p),
        ("GetSymbolOffset", c_void_p),
        ("GetSymbolRegister", c_void_p),
        ("GetSymbolValueText", ids_getsymbolvaluetext),
        ("GetSymbolValueTextWide", c_void_p),
        ("GetSymbolEntryInformation", c_void_p),
    ]


IDebugSymbolGroup2._fields_ = [("lpVtbl", POINTER(IDebugSymbolGroup2Vtbl))]


class SymbolGroup(object):
    def __init__(self, symgroup):
        self.symgroup = symgroup.contents
        self.vt = self.symgroup.lpVtbl.contents
        self.ulong = c_ulong()

    def GetNumberSymbols(self):
        res = self.vt.GetNumberSymbols(self.symgroup, byref(self.ulong))
        aborter(res, "GetNumberSymbols")
        return self.ulong.value

    def GetSymbolName(self, idx):
        buf = create_string_buffer(256)
        res = self.vt.GetSymbolName(self.symgroup, idx, buf, 255, byref(self.ulong))
        aborter(res, "GetSymbolName")
        thelen = self.ulong.value
        return string_at(buf).decode("ascii")

    def GetSymbolTypeName(self, idx):
        buf = create_string_buffer(256)
        res = self.vt.GetSymbolTypeName(self.symgroup, idx, buf, 255, byref(self.ulong))
        aborter(res, "GetSymbolTypeName")
        thelen = self.ulong.value
        return string_at(buf).decode("ascii")

    def GetSymbolValueText(self, idx, handleserror=False):
        buf = create_string_buffer(256)
        res = self.vt.GetSymbolValueText(
            self.symgroup, idx, buf, 255, byref(self.ulong)
        )
        if res != 0 and handleserror:
            return None
        aborter(res, "GetSymbolTypeName")
        thelen = self.ulong.value
        return string_at(buf).decode("ascii")

    def get_symbol(self, idx):
        name = self.GetSymbolName(idx)
        thetype = self.GetSymbolTypeName(idx)
        value = self.GetSymbolValueText(idx)
        return Symbol(idx, name, thetype, value)

    def get_all_symbols(self):
        num_syms = self.GetNumberSymbols()
        return list(map(self.get_symbol, list(range(num_syms))))
