import ctypes
import glob
import os
import platform

from chip.server.types import PostAttributeChangeCallback

NATIVE_LIBRARY_BASE_NAME = "_ChipServer.so"


def _AllDirsToRoot(dir):
    """Return all parent paths of a directory."""
    dir = os.path.abspath(dir)
    while True:
        yield dir
        parent = os.path.dirname(dir)
        if parent == "" or parent == dir:
            break
        dir = parent


def FindNativeLibraryPath() -> str:
    """Find the native CHIP dll/so path."""

    scriptDir = os.path.dirname(os.path.abspath(__file__))

    # When properly installed in the chip package, the Chip Device Manager DLL will
    # be located in the package root directory, along side the package's
    # modules.
    dmDLLPath = os.path.join(
        os.path.dirname(scriptDir),  # file should be inside 'chip'
        NATIVE_LIBRARY_BASE_NAME,
    )
    if os.path.exists(dmDLLPath):
        return dmDLLPath

    # For the convenience of developers, search the list of parent paths relative to the
    # running script looking for an CHIP build directory containing the Chip Device
    # Manager DLL. This makes it possible to import and use the ChipDeviceMgr module
    # directly from a built copy of the CHIP source tree.
    buildMachineGlob = "%s-*-%s*" % (platform.machine(),
                                     platform.system().lower())
    relDMDLLPathGlob = os.path.join(
        "build",
        buildMachineGlob,
        "src/controller/python/.libs",
        NATIVE_LIBRARY_BASE_NAME,
    )
    for dir in _AllDirsToRoot(scriptDir):
        dmDLLPathGlob = os.path.join(dir, relDMDLLPathGlob)
        for dmDLLPath in glob.glob(dmDLLPathGlob):
            if os.path.exists(dmDLLPath):
                return dmDLLPath

    raise Exception(
        "Unable to locate Chip Server DLL (%s); expected location: %s"
        % (NATIVE_LIBRARY_BASE_NAME, scriptDir)
    )


class NativeLibraryHandleMethodArguments:
    """Convenience wrapper to set native method argtype and restype for methods."""

    def __init__(self, handle):
        self.handle = handle

    def Set(self, methodName: str, resultType, argumentTypes: list):
        method = getattr(self.handle, methodName)
        method.restype = resultType
        method.argtype = argumentTypes


_nativeLibraryHandle: ctypes.CDLL = None


def GetLibraryHandle(cb: PostAttributeChangeCallback) -> ctypes.CDLL:
    """Get a memoized handle to the chip native code dll."""

    global _nativeLibraryHandle
    if _nativeLibraryHandle is None:
        _nativeLibraryHandle = ctypes.CDLL(FindNativeLibraryPath())

        setter = NativeLibraryHandleMethodArguments(_nativeLibraryHandle)
        setter.Set("pychip_server_native_init", None, [])
        setter.Set("pychip_server_set_callbacks",
                   None, [PostAttributeChangeCallback])

        _nativeLibraryHandle.pychip_server_native_init()
        _nativeLibraryHandle.pychip_server_set_callbacks(cb)

    return _nativeLibraryHandle
