#
#    Copyright (c) 2020 Project CHIP Authors
#    Copyright (c) 2020 Google LLC.
#    All rights reserved.
#
#    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.
#

#
#    @file
#      Python interface for Chip Stack
#

"""Chip Stack interface
"""

from __future__ import absolute_import, print_function

import asyncio
import builtins
import logging
import os
import sys
import time
from ctypes import (CFUNCTYPE, POINTER, Structure, c_bool, c_char_p, c_int64, c_uint8, c_uint16, c_uint32, c_ulong, c_void_p,
                    py_object, pythonapi)
from threading import Condition, Event, Lock

import chip.native
from chip.native import PyChipError

from .ChipUtility import ChipUtility
from .clusters import Attribute as ClusterAttribute
from .clusters import Command as ClusterCommand
from .exceptions import ChipStackError, ChipStackException, DeviceError
from .interaction_model import delegate as im
from .storage import PersistentStorage

__all__ = [
    "DeviceStatusStruct",
    "ChipStackException",
    "DeviceError",
    "ChipStackError",
    "ChipStack",
]

ChipStackDLLBaseName = "_ChipDeviceCtrl.so"


def _singleton(cls):
    instance = [None]

    def wrapper(*args, **kwargs):
        if instance[0] is None:
            instance[0] = cls(*args, **kwargs)
        return instance[0]

    return wrapper


class DeviceStatusStruct(Structure):
    _fields_ = [
        ("ProfileId", c_uint32),
        ("StatusCode", c_uint16),
        ("SysErrorCode", c_uint32),
    ]


class LogCategory(object):
    """Debug logging categories used by chip."""

    # NOTE: These values must correspond to those used in the chip C++ code.
    Disabled = 0
    Error = 1
    Progress = 2
    Detail = 3
    Retain = 4

    @staticmethod
    def categoryToLogLevel(cat):
        if cat == LogCategory.Error:
            return logging.ERROR
        elif cat == LogCategory.Progress:
            return logging.INFO
        elif cat == LogCategory.Detail:
            return logging.DEBUG
        elif cat == LogCategory.Retain:
            return logging.CRITICAL
        else:
            return logging.NOTSET


class ChipLogFormatter(logging.Formatter):
    """A custom logging.Formatter for logging chip library messages."""

    def __init__(
        self,
        datefmt=None,
        logModulePrefix=False,
        logLevel=False,
        logTimestamp=False,
        logMSecs=True,
    ):
        fmt = "%(message)s"
        if logModulePrefix:
            fmt = "CHIP:%(chip-module)s: " + fmt
        if logLevel:
            fmt = "%(levelname)s:" + fmt
        if datefmt is not None or logTimestamp:
            fmt = "%(asctime)s " + fmt
        super(ChipLogFormatter, self).__init__(fmt=fmt, datefmt=datefmt)
        self.logMSecs = logMSecs

    def formatTime(self, record, datefmt=None):
        if datefmt is None:
            timestampStr = time.strftime("%Y-%m-%d %H:%M:%S%z")
        if self.logMSecs:
            timestampUS = record.__dict__.get("timestamp-usec", 0)
            timestampStr = "%s.%03ld" % (timestampStr, timestampUS / 1000)
        return timestampStr


class AsyncCallableHandle:
    def __init__(self, callback):
        self._callback = callback
        self._res = None
        self._exc = None
        self._finish = False
        self._cv_lock = Lock()
        self._cv = Condition(self._cv_lock)

    def __call__(self):
        with self._cv_lock:
            try:
                self._res = self._callback()
            except Exception as ex:
                self._exc = ex
            self._finish = True
            self._cv.notify_all()
        pythonapi.Py_DecRef(py_object(self))

    def Wait(self, timeoutMs: int = None):
        timeout = None
        if timeoutMs is not None:
            timeout = float(timeoutMs) / 1000

        with self._cv:
            while self._finish is False:
                res = self._cv.wait(timeout)
                if res is False:
                    raise TimeoutError("Timed out waiting for task to finish executing on the Matter thread")

            if self._exc is not None:
                raise self._exc
            return self._res


class AsyncioCallableHandle:
    """Class which handles Matter SDK Calls asyncio friendly"""

    def __init__(self, callback):
        self._callback = callback
        self._loop = asyncio.get_event_loop()
        self._future = self._loop.create_future()
        self._result = None
        self._exception = None

    @property
    def future(self):
        return self._future

    def _done(self):
        if self._exception:
            self._future.set_exception(self._exception)
        else:
            self._future.set_result(self._result)

    def __call__(self):
        try:
            self._result = self._callback()
        except Exception as ex:
            self._exception = ex
        self._loop.call_soon_threadsafe(self._done)
        pythonapi.Py_DecRef(py_object(self))


_CompleteFunct = CFUNCTYPE(None, c_void_p, c_void_p)
_ErrorFunct = CFUNCTYPE(None, c_void_p, c_void_p,
                        c_ulong, POINTER(DeviceStatusStruct))
_LogMessageFunct = CFUNCTYPE(
    None, c_int64, c_int64, c_char_p, c_uint8, c_char_p)
_ChipThreadTaskRunnerFunct = CFUNCTYPE(None, py_object)


@_singleton
class ChipStack(object):
    def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True,
                 bluetoothAdapter=None, enableServerInteractions=True):
        builtins.enableDebugMode = False

        # TODO: Probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321.
        self.networkLock = Lock()
        self.completeEvent = Event()
        self.commissioningCompleteEvent = Event()
        self._ChipStackLib = None
        self._chipDLLPath = None
        self.devMgr = None
        self.callbackRes = None
        self.commissioningEventRes = None
        self.openCommissioningWindowPincode = {}
        self._activeLogFunct = None
        self.addModulePrefixToLogMessage = True
        self._enableServerInteractions = enableServerInteractions

        #
        # Locate and load the chip shared library.
        # This also implictly does a minimal stack initialization (i.e call MemoryInit).
        #
        self._loadLib()

        # Arrange to log output from the chip library to a python logger object with the
        # name 'chip.ChipStack'.  If desired, applications can override this behavior by
        # setting self.logger to a different python logger object, or by calling setLogFunct()
        # with their own logging function.
        self.logger = logging.getLogger(__name__)
        self.setLogFunct(self.defaultLogFunct)

        # Determine if there are already handlers installed for the logger.  Python 3.5+
        # has a method for this; on older versions the check has to be done manually.
        if hasattr(self.logger, "hasHandlers"):
            hasHandlers = self.logger.hasHandlers()
        else:
            hasHandlers = False
            logger = self.logger
            while logger is not None:
                if len(logger.handlers) > 0:
                    hasHandlers = True
                    break
                if not logger.propagate:
                    break
                logger = logger.parent

        # If a logging handler has not already been initialized for 'chip.ChipStack',
        # or any one of its parent loggers, automatically configure a handler to log to
        # stdout.  This maintains compatibility with a number of applications which expect
        # chip log output to go to stdout by default.
        #
        # This behavior can be overridden in a variety of ways:
        #     - Initialize a different log handler before ChipStack is initialized.
        #     - Pass installDefaultLogHandler=False when initializing ChipStack.
        #     - Replace the StreamHandler on self.logger with a different handler object.
        #     - Set a different Formatter object on the existing StreamHandler object.
        #     - Reconfigure the existing ChipLogFormatter object.
        #     - Configure chip to call an application-specific logging function by
        #       calling self.setLogFunct().
        #     - Call self.setLogFunct(None), which will configure the chip library
        #       to log directly to stdout, bypassing python altogether.
        #
        if installDefaultLogHandler and not hasHandlers:
            logHandler = logging.StreamHandler(stream=sys.stdout)
            logHandler.setFormatter(ChipLogFormatter())
            self.logger.addHandler(logHandler)
            self.logger.setLevel(logging.DEBUG)

        def HandleComplete(appState, reqState):
            self.callbackRes = True
            self.completeEvent.set()

        def HandleError(appState, reqState, err, devStatusPtr):
            self.callbackRes = self.ErrorToException(err, devStatusPtr)
            self.completeEvent.set()

        @_ChipThreadTaskRunnerFunct
        def HandleChipThreadRun(callback):
            callback()

        self.cbHandleChipThreadRun = HandleChipThreadRun
        self.cbHandleComplete = _CompleteFunct(HandleComplete)
        self.cbHandleError = _ErrorFunct(HandleError)
        # set by other modules(BLE) that require service by thread while thread blocks.
        self.blockingCB = None

        #
        # Storage has to be initialized BEFORE initializing the stack, since the latter
        # requires a PersistentStorageDelegate to be provided to DeviceControllerFactory.
        #
        self._persistentStorage = PersistentStorage(persistentStoragePath)

        # Initialize the chip stack.
        res = self._ChipStackLib.pychip_DeviceController_StackInit(
            self._persistentStorage.GetSdkStorageObject(), enableServerInteractions)
        res.raise_on_error()

        im.InitIMDelegate()
        ClusterAttribute.Init()
        ClusterCommand.Init()

        builtins.chipStack = self

    def GetStorageManager(self):
        return self._persistentStorage

    @property
    def enableServerInteractions(self):
        return self._enableServerInteractions

    @property
    def defaultLogFunct(self):
        """Returns a python callable which, when called, logs a message to the python logger object
        currently associated with the ChipStack object.
        The returned function is suitable for passing to the setLogFunct() method."""

        def logFunct(timestamp, timestampUSec, moduleName, logCat, message):
            moduleName = ChipUtility.CStringToString(moduleName)
            message = ChipUtility.CStringToString(message)
            if self.addModulePrefixToLogMessage:
                message = "CHIP:%s: %s" % (moduleName, message)
            logLevel = LogCategory.categoryToLogLevel(logCat)
            msgAttrs = {
                "chip-module": moduleName,
                "timestamp": timestamp,
                "timestamp-usec": timestampUSec,
            }
            self.logger.log(logLevel, message, extra=msgAttrs)

        return logFunct

    def setLogFunct(self, logFunct):
        """Set the function used by the chip library to log messages.
        The supplied object must be a python callable that accepts the following
        arguments:
           timestamp (integer)
           timestampUS (integer)
           module name (encoded UTF-8 string)
           log category (integer)
           message (encoded UTF-8 string)
        Specifying None configures the chip library to log directly to stdout."""
        if logFunct is None:
            logFunct = 0
        if not isinstance(logFunct, _LogMessageFunct):
            logFunct = _LogMessageFunct(logFunct)
        # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321.
        with self.networkLock:
            # NOTE: ChipStack must hold a reference to the CFUNCTYPE object while it is
            # set. Otherwise it may get garbage collected, and logging calls from the
            # chip library will fail.
            self._activeLogFunct = logFunct
            self._ChipStackLib.pychip_Stack_SetLogFunct(logFunct)

    def Shutdown(self):
        #
        # Terminate Matter thread and shutdown the stack.
        #
        self._ChipStackLib.pychip_DeviceController_StackShutdown()

        #
        # We only shutdown the persistent storage layer AFTER we've shut down the stack,
        # since there is a possibility of interactions with the storage layer during shutdown.
        #
        self._persistentStorage.Shutdown()
        self._persistentStorage = None

        #
        # Stack init happens in native, but shutdown happens here unfortunately.
        # #20437 tracks consolidating these.
        #
        self._ChipStackLib.pychip_CommonStackShutdown()
        self.networkLock = None
        self.completeEvent = None
        self._ChipStackLib = None
        self._chipDLLPath = None
        self.devMgr = None
        self.callbackRes = None

        delattr(builtins, "chipStack")

    def Call(self, callFunct, timeoutMs: int = None):
        '''Run a Python function on CHIP stack, and wait for the response.
        This function is a wrapper of PostTaskOnChipThread, which includes some handling of application specific logics.
        Calling this function on CHIP on CHIP mainloop thread will cause deadlock.
        '''
        # throw error if op in progress
        self.callbackRes = None
        self.completeEvent.clear()
        # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321.
        with self.networkLock:
            res = self.PostTaskOnChipThread(callFunct).Wait(timeoutMs)
        self.completeEvent.set()
        if res == 0 and self.callbackRes is not None:
            return self.callbackRes
        return res

    async def CallAsync(self, callFunct, timeoutMs: int = None):
        '''Run a Python function on CHIP stack, and wait for the response.
        This function will post a task on CHIP mainloop and waits for the call response in a asyncio friendly manner.
        '''
        callObj = AsyncioCallableHandle(callFunct)
        pythonapi.Py_IncRef(py_object(callObj))

        res = self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread(
            self.cbHandleChipThreadRun, py_object(callObj))

        if not res.is_success:
            pythonapi.Py_DecRef(py_object(callObj))
            raise res.to_exception()

        return await asyncio.wait_for(callObj.future, timeoutMs / 1000 if timeoutMs else None)

    def CallAsyncWithCompleteCallback(self, callFunct):
        '''Run a Python function on CHIP stack, and wait for the application specific response.
        This function is a wrapper of PostTaskOnChipThread, which includes some handling of application specific logics.
        Calling this function on CHIP on CHIP mainloop thread will cause deadlock.
        Make sure to register the necessary callbacks which release the function by setting the completeEvent.
        '''
        # throw error if op in progress
        self.callbackRes = None
        self.completeEvent.clear()
        # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321.
        with self.networkLock:
            res = self.PostTaskOnChipThread(callFunct).Wait()

        if not res.is_success:
            self.completeEvent.set()
            raise res.to_exception()
        while not self.completeEvent.isSet():
            if self.blockingCB:
                self.blockingCB()

            self.completeEvent.wait(0.05)
        if isinstance(self.callbackRes, ChipStackException):
            raise self.callbackRes
        return self.callbackRes

    def PostTaskOnChipThread(self, callFunct) -> AsyncCallableHandle:
        '''Run a Python function on CHIP stack, and wait for the response.
        This function will post a task on CHIP mainloop, and return an object with Wait() method for getting the result.
        Calling Wait inside main loop will cause deadlock.
        '''
        callObj = AsyncCallableHandle(callFunct)
        pythonapi.Py_IncRef(py_object(callObj))
        res = self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread(
            self.cbHandleChipThreadRun, py_object(callObj))
        if not res.is_success:
            pythonapi.Py_DecRef(py_object(callObj))
            raise res.to_exception()
        return callObj

    def ErrorToException(self, err, devStatusPtr=None):
        if err == 0x2C and devStatusPtr:
            devStatus = devStatusPtr.contents
            msg = ChipUtility.CStringToString(
                (
                    self._ChipStackLib.pychip_Stack_StatusReportToString(
                        devStatus.ProfileId, devStatus.StatusCode
                    )
                )
            )
            sysErrorCode = (
                devStatus.SysErrorCode if (
                    devStatus.SysErrorCode != 0) else None
            )
            if sysErrorCode is not None:
                msg = msg + " (system err %d)" % (sysErrorCode)
            return DeviceError(
                devStatus.ProfileId, devStatus.StatusCode, sysErrorCode, msg
            )
        else:
            return ChipStackError(
                err,
                ChipUtility.CStringToString(
                    (self._ChipStackLib.pychip_Stack_ErrorToString(err))
                ),
            )

    def LocateChipDLL(self):
        self._loadLib()
        return self._chipDLLPath

    # ----- Private Members -----
    def _AllDirsToRoot(self, dir):
        dir = os.path.abspath(dir)
        while True:
            yield dir
            parent = os.path.dirname(dir)
            if parent == "" or parent == dir:
                break
            dir = parent

    def _loadLib(self):
        if self._ChipStackLib is None:
            self._ChipStackLib = chip.native.GetLibraryHandle()
            self._chipDLLPath = chip.native.FindNativeLibraryPath(chip.native.Library.CONTROLLER)

            self._ChipStackLib.pychip_DeviceController_StackInit.argtypes = [c_void_p, c_bool]
            self._ChipStackLib.pychip_DeviceController_StackInit.restype = PyChipError
            self._ChipStackLib.pychip_DeviceController_StackShutdown.argtypes = []
            self._ChipStackLib.pychip_DeviceController_StackShutdown.restype = PyChipError
            self._ChipStackLib.pychip_Stack_StatusReportToString.argtypes = [
                c_uint32,
                c_uint16,
            ]
            self._ChipStackLib.pychip_Stack_StatusReportToString.restype = c_char_p
            self._ChipStackLib.pychip_Stack_ErrorToString.argtypes = [c_uint32]
            self._ChipStackLib.pychip_Stack_ErrorToString.restype = c_char_p
            self._ChipStackLib.pychip_Stack_SetLogFunct.argtypes = [
                _LogMessageFunct]
            self._ChipStackLib.pychip_Stack_SetLogFunct.restype = PyChipError

            self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread.argtypes = [
                _ChipThreadTaskRunnerFunct, py_object]
            self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread.restype = PyChipError
