<reponame>FastyBird/miniserver-gateway
#     Copyright 2021. FastyBird s.r.o.
#
#     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.

"""
Tuya connector module
"""

import logging

# Python base dependencies
import uuid
from datetime import datetime
from threading import Thread
from typing import Optional, Union

# App dependencies
from kink import inject
from modules_metadata.devices_module import ConnectorType
from modules_metadata.types import ButtonPayload, SwitchPayload

# App libs
from miniserver_gateway.connectors.iconnector import IConnector
from miniserver_gateway.connectors.queue_items import IQueueItem
from miniserver_gateway.connectors.tuya.logger import Logger


class TuyaConnector:  # pylint: disable=too-many-instance-attributes,too-many-public-methods
    """
    Tuya connector service

    @package        FastyBird:TuyaConnectorPlugin!
    @module         connector

    @author         <NAME> <<EMAIL>>
    """

    __stopped: bool = False

    __logger: Logger

    # -----------------------------------------------------------------------------

    def __init__(  # pylint: disable=too-many-arguments
        self,
        logger: Logger,
    ) -> None:
        self.__logger = logger

    # -----------------------------------------------------------------------------

    def configure_client(  # pylint: disable=too-many-arguments
        self,
        client_id: uuid.UUID,
    ) -> None:
        """Configure Tuya clients & append them to client proxy"""

    # -----------------------------------------------------------------------------

    def enable_client(self, client_id: uuid.UUID) -> bool:
        """Enable client"""

    # -----------------------------------------------------------------------------

    def disable_client(self, client_id: uuid.UUID) -> bool:
        """Disable client connector"""

    # -----------------------------------------------------------------------------

    def remove_client(self, client_id: uuid.UUID) -> bool:
        """Remove client from connector"""

    # -----------------------------------------------------------------------------

    def reset_clients(self) -> None:
        """Reset all connector clients"""

    # -----------------------------------------------------------------------------

    def initialize_device(  # pylint: disable=too-many-arguments,too-many-locals
        self,
        client_id: uuid.UUID,
        device_id: uuid.UUID,
        device_identifier: str,
        device_type: Optional[str] = None,
        device_enabled: bool = False,
    ) -> None:
        """Configure device record in connector registry"""

    # -----------------------------------------------------------------------------

    def remove_device(self, device_id: uuid.UUID) -> None:
        """Remove device from connector registry"""

    # -----------------------------------------------------------------------------

    def reset_devices(self, client_id: Optional[uuid.UUID] = None) -> None:
        """Reset devices registry to initial state"""

    # -----------------------------------------------------------------------------

    def start(self) -> None:
        """Start connector services"""
        self.__stopped = False

        self.__logger.info(
            "Connector has been started",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

    # -----------------------------------------------------------------------------

    def stop(self) -> None:
        """Close all opened connections & stop connector thread"""
        self.__logger.info(
            "Connector has been stopped",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

        self.__stopped = True

    # -----------------------------------------------------------------------------

    @staticmethod
    def has_unfinished_tasks() -> bool:
        """Check if connector has some unfinished task"""
        return False

    # -----------------------------------------------------------------------------

    def loop(self) -> None:
        """Run connector service"""
        if self.__stopped and not self.has_unfinished_tasks():
            self.__logger.warning(
                "Connector is stopped and can't process another requests",
                extra={
                    "connector": ConnectorType.MODBUS.value,
                },
            )

            return

        if self.__stopped:
            return


@inject
class TuyaConnectorWrapper(IConnector, Thread):  # pylint: disable=too-many-instance-attributes
    """
    Tuya connector service

    @package        FastyBird:MiniServer!
    @module         connector

    @author         <NAME> <<EMAIL>.<EMAIL>>
    """

    __stopped: bool = True

    __connector: TuyaConnector

    __logger: logging.Logger

    # -----------------------------------------------------------------------------

    def __init__(  # pylint: disable=too-many-arguments
        self,
        connector: TuyaConnector,
        logger: logging.Logger,
    ) -> None:
        Thread.__init__(self, name="Tuya connector thread", daemon=True)

        self.__connector = connector

        self.__logger = logger

    # -----------------------------------------------------------------------------

    def start(self) -> None:
        """Start connector service"""
        self.__connector.start()

        self.__stopped = False

        Thread.start(self)

    # -----------------------------------------------------------------------------

    def stop(self) -> None:
        """Stop connector service"""
        self.__connector.stop()

        self.__stopped = True

    # -----------------------------------------------------------------------------

    def is_alive(self) -> bool:
        """Check if connector has some task to process"""
        return self.__connector.has_unfinished_tasks() or Thread.is_alive(self)

    # -----------------------------------------------------------------------------

    def process_queue_item(self, item: IQueueItem) -> None:
        """Process item popped from queue"""

    # -----------------------------------------------------------------------------

    def run(self) -> None:
        """Process connector loop"""
        while True:
            # All tasks have to be processed before thread is closed
            if self.__stopped and not self.__connector.has_unfinished_tasks():
                break

            self.__connector.loop()

    # -----------------------------------------------------------------------------

    def clone(self) -> "TuyaConnectorWrapper":
        """Restart connector thread"""
        self.__logger.debug(
            "Restarting connector thread",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

        return TuyaConnectorWrapper(
            connector=self.__connector,
            logger=self.__logger,
        )

#     Copyright 2021. FastyBird s.r.o.
#
#     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.

"""
Tuya connector module
"""

import logging

# Python base dependencies
import uuid
from datetime import datetime
from threading import Thread
from typing import Optional, Union

# App dependencies
from kink import inject
from modules_metadata.devices_module import ConnectorType
from modules_metadata.types import ButtonPayload, SwitchPayload

# App libs
from miniserver_gateway.connectors.iconnector import IConnector
from miniserver_gateway.connectors.queue_items import IQueueItem
from miniserver_gateway.connectors.tuya.logger import Logger


class TuyaConnector:  # pylint: disable=too-many-instance-attributes,too-many-public-methods
    """
    Tuya connector service

    @package        FastyBird:TuyaConnectorPlugin!
    @module         connector

    @author         <NAME> <<EMAIL>>
    """

    __stopped: bool = False

    __logger: Logger

    # -----------------------------------------------------------------------------

    def __init__(  # pylint: disable=too-many-arguments
        self,
        logger: Logger,
    ) -> None:
        self.__logger = logger

    # -----------------------------------------------------------------------------

    def configure_client(  # pylint: disable=too-many-arguments
        self,
        client_id: uuid.UUID,
    ) -> None:
        """Configure Tuya clients & append them to client proxy"""

    # -----------------------------------------------------------------------------

    def enable_client(self, client_id: uuid.UUID) -> bool:
        """Enable client"""

    # -----------------------------------------------------------------------------

    def disable_client(self, client_id: uuid.UUID) -> bool:
        """Disable client connector"""

    # -----------------------------------------------------------------------------

    def remove_client(self, client_id: uuid.UUID) -> bool:
        """Remove client from connector"""

    # -----------------------------------------------------------------------------

    def reset_clients(self) -> None:
        """Reset all connector clients"""

    # -----------------------------------------------------------------------------

    def initialize_device(  # pylint: disable=too-many-arguments,too-many-locals
        self,
        client_id: uuid.UUID,
        device_id: uuid.UUID,
        device_identifier: str,
        device_type: Optional[str] = None,
        device_enabled: bool = False,
    ) -> None:
        """Configure device record in connector registry"""

    # -----------------------------------------------------------------------------

    def remove_device(self, device_id: uuid.UUID) -> None:
        """Remove device from connector registry"""

    # -----------------------------------------------------------------------------

    def reset_devices(self, client_id: Optional[uuid.UUID] = None) -> None:
        """Reset devices registry to initial state"""

    # -----------------------------------------------------------------------------

    def start(self) -> None:
        """Start connector services"""
        self.__stopped = False

        self.__logger.info(
            "Connector has been started",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

    # -----------------------------------------------------------------------------

    def stop(self) -> None:
        """Close all opened connections & stop connector thread"""
        self.__logger.info(
            "Connector has been stopped",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

        self.__stopped = True

    # -----------------------------------------------------------------------------

    @staticmethod
    def has_unfinished_tasks() -> bool:
        """Check if connector has some unfinished task"""
        return False

    # -----------------------------------------------------------------------------

    def loop(self) -> None:
        """Run connector service"""
        if self.__stopped and not self.has_unfinished_tasks():
            self.__logger.warning(
                "Connector is stopped and can't process another requests",
                extra={
                    "connector": ConnectorType.MODBUS.value,
                },
            )

            return

        if self.__stopped:
            return


@inject
class TuyaConnectorWrapper(IConnector, Thread):  # pylint: disable=too-many-instance-attributes
    """
    Tuya connector service

    @package        FastyBird:MiniServer!
    @module         connector

    @author         <NAME> <<EMAIL>.<EMAIL>>
    """

    __stopped: bool = True

    __connector: TuyaConnector

    __logger: logging.Logger

    # -----------------------------------------------------------------------------

    def __init__(  # pylint: disable=too-many-arguments
        self,
        connector: TuyaConnector,
        logger: logging.Logger,
    ) -> None:
        Thread.__init__(self, name="Tuya connector thread", daemon=True)

        self.__connector = connector

        self.__logger = logger

    # -----------------------------------------------------------------------------

    def start(self) -> None:
        """Start connector service"""
        self.__connector.start()

        self.__stopped = False

        Thread.start(self)

    # -----------------------------------------------------------------------------

    def stop(self) -> None:
        """Stop connector service"""
        self.__connector.stop()

        self.__stopped = True

    # -----------------------------------------------------------------------------

    def is_alive(self) -> bool:
        """Check if connector has some task to process"""
        return self.__connector.has_unfinished_tasks() or Thread.is_alive(self)

    # -----------------------------------------------------------------------------

    def process_queue_item(self, item: IQueueItem) -> None:
        """Process item popped from queue"""

    # -----------------------------------------------------------------------------

    def run(self) -> None:
        """Process connector loop"""
        while True:
            # All tasks have to be processed before thread is closed
            if self.__stopped and not self.__connector.has_unfinished_tasks():
                break

            self.__connector.loop()

    # -----------------------------------------------------------------------------

    def clone(self) -> "TuyaConnectorWrapper":
        """Restart connector thread"""
        self.__logger.debug(
            "Restarting connector thread",
            extra={
                "connector": ConnectorType.MODBUS.value,
            },
        )

        return TuyaConnectorWrapper(
            connector=self.__connector,
            logger=self.__logger,
        )
#     Copyright 2021. FastyBird s.r.o. # #     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. Tuya connector module # Python base dependencies # App dependencies # App libs # pylint: disable=too-many-instance-attributes,too-many-public-methods Tuya connector service      @package        FastyBird:TuyaConnectorPlugin!     @module         connector      @author         <NAME> <<EMAIL>> # ----------------------------------------------------------------------------- # pylint: disable=too-many-arguments # ----------------------------------------------------------------------------- # pylint: disable=too-many-arguments Configure Tuya clients & append them to client proxy # ----------------------------------------------------------------------------- Enable client # ----------------------------------------------------------------------------- Disable client connector # ----------------------------------------------------------------------------- Remove client from connector # ----------------------------------------------------------------------------- Reset all connector clients # ----------------------------------------------------------------------------- # pylint: disable=too-many-arguments,too-many-locals Configure device record in connector registry # ----------------------------------------------------------------------------- Remove device from connector registry # ----------------------------------------------------------------------------- Reset devices registry to initial state # ----------------------------------------------------------------------------- Start connector services # ----------------------------------------------------------------------------- Close all opened connections & stop connector thread # ----------------------------------------------------------------------------- Check if connector has some unfinished task # ----------------------------------------------------------------------------- Run connector service # pylint: disable=too-many-instance-attributes Tuya connector service      @package        FastyBird:MiniServer!     @module         connector      @author         <NAME> <<EMAIL>.<EMAIL>> # ----------------------------------------------------------------------------- # pylint: disable=too-many-arguments # ----------------------------------------------------------------------------- Start connector service # ----------------------------------------------------------------------------- Stop connector service # ----------------------------------------------------------------------------- Check if connector has some task to process # ----------------------------------------------------------------------------- Process item popped from queue # ----------------------------------------------------------------------------- Process connector loop # All tasks have to be processed before thread is closed # ----------------------------------------------------------------------------- Restart connector thread