# Copyright 2021 Google LLC
#
# 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.

"""Module for light command handler."""
from typing import Any, Dict

from gazoo_device import errors

from local_agent import logger as logger_module
from local_agent.translation_layer.command_handlers import base


logger = logger_module.get_logger()

PWRPC_LIGHT_CAPABILITY = 'pw_rpc_light'

# OnOff Response States:
LIGHT_ON = 'on'
LIGHT_OFF = 'off'


class LightCommandHandler(base.BaseCommandHandler):
    """Lighting device command handler

    Smart Home OnOff Trait Schema:
    https://developers.google.com/assistant/smarthome/traits/onoff
    """

    _GET_STATE = 'getOnOff'
    _SET_STATE_ON = 'setOn'
    _SET_STATE_OFF = 'setOff'
    _GET_BRIGHTNESS = 'getBrightness'
    _SET_BRIGHTNESS = 'setBrightness'
    _GET_COLOR = 'getColor'
    _SET_COLOR = 'setColor'

    SUPPORTED_METHODS = {
        _GET_STATE,
        _SET_STATE_ON,
        _SET_STATE_OFF,
        _GET_BRIGHTNESS,
        _SET_BRIGHTNESS,
        _GET_COLOR,
        _SET_COLOR}

    def _get_on_off(self, params: Dict[str, Any]) -> str:
        """Queries the light state of the device.

        Returns:
            The light state.

        Raises:
            DeviceError: getting light state fails.
        """
        del params  # not used
        try:
            return LIGHT_ON if self.dut.pw_rpc_light.state else LIGHT_OFF
        except errors.DeviceError as exc:
            logger.exception(f'Getting light state of {self.dut.name} failed.')
            raise exc

    def _set_on(self, params: Dict[str, Any]) -> None:
        """Turns on the light of the device.

        Raises:
            DeviceError: turning light on fails.
        """
        del params  # not used
        try:
            self.dut.pw_rpc_light.on()
        except errors.DeviceError as exc:
            logger.exception(f'Turning {self.dut.name} on failed.')
            raise exc

    def _set_off(self, params: Dict[str, Any]) -> None:
        """Turns off the light of the device.

        Raises:
            DeviceError: turning light off fails.
        """
        del params  # not used
        try:
            self.dut.pw_rpc_light.off()
        except errors.DeviceError as exc:
            logger.exception(f'Turning {self.dut.name} off failed.')
            raise exc

    def _get_brightness(self, params: Dict[str, Any]) -> int:
        """Queries the current brightness level of the device.

        Returns:
            The current brightness level.

        Raises:
            DeviceError: getting light brightness fails.
        """
        del params  # not used
        try:
            return self.dut.pw_rpc_light.brightness
        except errors.DeviceError as exc:
            logger.exception(
                f'Getting light brightness of {self.dut.name} failed.')
            raise exc

    def _set_brightness(self, params: Dict[str, Any]) -> None:
        """Sets the current brightness level of the device.

        Raises:
            DeviceError: setting brightness level fails.
        """
        self.validate_key_in_params(
            params=params, param_key='level', expected_type=int)

        try:
            self.dut.pw_rpc_light.on(level=params['level'])
        except errors.DeviceError as exc:
            logger.exception(
                f'Setting light brightness of {self.dut.name} failed.')
            raise exc

    def _get_color(self, params: Dict[str, Any]) -> Dict[str, int]:
        """Gets the current lighting color of the device.

        Returns:
            The current hue and saturation values in dict.

        Raises:
            DeviceError: getting color fails.
        """
        del params
        try:
            hue = self.dut.pw_rpc_light.color.hue
            saturation = self.dut.pw_rpc_light.color.saturation
        except errors.DeviceError as exc:
            logger.exception(
               f'Getting light color of {self.dut.name} failed.')
            raise exc
        return {'hue': hue, 'saturation': saturation}

    def _set_color(self, params: Dict[str, Any]) -> None:
        """Sets the lighting color to specific hue and saturation.

        Raises:
            DeviceError: setting color fails.
        """
        self.validate_key_in_params(
            params=params, param_key='hue', expected_type=int)
        self.validate_key_in_params(
            params=params, param_key='saturation', expected_type=int)

        try:
            hue = params['hue']
            saturation = params['saturation']
            self.dut.pw_rpc_light.on(hue=hue, saturation=saturation)
        except errors.DeviceError as exc:
            logger.exception(
               f'Setting light color of {self.dut.name} failed.')
            raise exc
