/*
 *    Copyright (c) 2022 Project CHIP Authors
 *    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.
 */

#include "PWMDevice.h"

#include "AppConfig.h"

#include <lib/support/CodeUtils.h>

#include <zephyr/drivers/pwm.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(app);

constexpr uint32_t kBreatheStepTimeMS = 10;

static PWMDevice::PWMTimerCallback_fn mActionBlinkStateUpdate_CB;

CHIP_ERROR PWMDevice::Init(const pwm_dt_spec * pwmDevice, uint8_t aMinLevel, uint8_t aMaxLevel, uint8_t aDefaultLevel)
{
    // We use a gpioPin instead of a LEDWidget here because we want to use PWM
    // and other features instead of just on/off.

    mState     = kState_On;
    mMinLevel  = aMinLevel;
    mMaxLevel  = aMaxLevel;
    mLevel     = aDefaultLevel;
    mPwmDevice = pwmDevice;

    if (!device_is_ready(mPwmDevice->dev))
    {
        LOG_ERR("PWM device %s is not ready", mPwmDevice->dev->name);
        return CHIP_ERROR_INCORRECT_STATE;
    }

    k_timer_init(&mPwmLedTimer, &PWMDevice::PwmLedTimerHandler, nullptr);
    k_timer_user_data_set(&mPwmLedTimer, this);

    ClearAction();
    Set(false);
    return CHIP_NO_ERROR;
}

void PWMDevice::SetCallbacks(PWMCallback_fn aActionInitiated_CB, PWMCallback_fn aActionCompleted_CB,
                             PWMTimerCallback_fn aActionBlinkStateUpdate_CB)
{
    mActionInitiated_CB        = aActionInitiated_CB;
    mActionCompleted_CB        = aActionCompleted_CB;
    mActionBlinkStateUpdate_CB = aActionBlinkStateUpdate_CB;
}

bool PWMDevice::InitiateAction(Action_t aAction, int32_t aActor, uint8_t * value)
{
    bool action_initiated = false;
    State_t new_state;

    // Initiate On/Off Action only when the previous one is complete.
    if (mState == kState_Off && aAction == ON_ACTION)
    {
        action_initiated = true;
        new_state        = kState_On;
    }
    else if (mState == kState_On && aAction == OFF_ACTION)
    {
        action_initiated = true;
        new_state        = kState_Off;
    }
    else if ((aAction == LEVEL_ACTION || aAction == COLOR_ACTION_XY || aAction == COLOR_ACTION_HSV || aAction == COLOR_ACTION_CT) &&
             *value != mLevel)
    {
        action_initiated = true;
        if (*value == 0)
        {
            new_state = kState_Off;
        }
        else
        {
            new_state = kState_On;
        }
    }

    if (action_initiated)
    {
        if (mActionInitiated_CB)
        {
            mActionInitiated_CB(aAction, aActor);
        }

        if (aAction == ON_ACTION || aAction == OFF_ACTION)
        {
            Set(new_state == kState_On);
        }
        else if (aAction == LEVEL_ACTION || aAction == COLOR_ACTION_XY || aAction == COLOR_ACTION_HSV || aAction == COLOR_ACTION_CT)
        {
            SetLevel(*value);
        }

        if (mActionCompleted_CB)
        {
            mActionCompleted_CB(aAction, aActor);
        }
    }

    return action_initiated;
}

void PWMDevice::SetLevel(uint8_t aLevel)
{
    LOG_DBG("Setting brightness level to %u", aLevel);
    mLevel = aLevel;
    UpdateLight();
}

void PWMDevice::Set(bool aOn)
{
    mState = aOn ? kState_On : kState_Off;
    UpdateLight();
}

void PWMDevice::UpdateLight(void)
{
    constexpr uint32_t kPwmWidthUs  = 20000u;
    const uint8_t maxEffectiveLevel = mMaxLevel - mMinLevel;
    const uint8_t effectiveLevel    = mState == kState_On ? chip::min<uint8_t>(mLevel - mMinLevel, maxEffectiveLevel) : 0;

    pwm_set(mPwmDevice->dev, mPwmDevice->channel, PWM_USEC(kPwmWidthUs), PWM_USEC(kPwmWidthUs * effectiveLevel / maxEffectiveLevel),
            0);
}

void PWMDevice::InitiateBlinkAction(uint32_t onTimeMS, uint32_t offTimeMS)
{
    ClearAction();

    if (onTimeMS != 0 && offTimeMS != 0)
    {
        mBlinkOnTimeMS  = onTimeMS;
        mBlinkOffTimeMS = offTimeMS;

        Set(mState != kState_On ? true : false);
        StartBlinkTimer();
    }
    else
    {
        LOG_ERR("Invalid InitiateBlinkAction parameters. onTimeMS = %u, offTimeMS = %u", onTimeMS, offTimeMS);
    }
}

void PWMDevice::InitiateBreatheAction(BreatheType_t type, uint32_t cycleTimeMS)
{
    ClearAction();

    if (type != kBreatheType_Invalid && cycleTimeMS != 0)
    {
        mBreatheType      = type;
        mBreatheStepNumb  = cycleTimeMS / kBreatheStepTimeMS;
        mBreatheStepLevel = (mMaxLevel - mMinLevel) / mBreatheStepNumb;

        if (mBreatheType == kBreatheType_Both)
        {
            mBreatheBothDirection = true;
            mBreatheType          = mState == kState_On ? kBreatheType_Falling : kBreatheType_Rising;
        }

        if (mBreatheType == kBreatheType_Falling)
        {
            mLevel = mMaxLevel;
        }
        else
        {
            mLevel = mMinLevel;
        }

        Set(true);
        StartBreatheTimer(kBreatheStepTimeMS);
    }
    else
    {
        LOG_ERR("Invalid InitiateBreatheAction parameters. Type = %u, cycleTimeMS = %u", type, cycleTimeMS);
    }
}

void PWMDevice::StopAction(void)
{
    ClearAction();
    Set(false);
}

void PWMDevice::UpdateAction(void)
{
    // Update of Breathe action
    if (mBreatheType != kBreatheType_Invalid && mBreatheStepLevel != 0 && mBreatheStepNumb != 0)
    {
        if (mBreatheStepCntr == mBreatheStepNumb)
        {
            mBreatheStepCntr = 0;
            if (mBreatheBothDirection)
            {
                mBreatheType = mBreatheType == kBreatheType_Rising ? kBreatheType_Falling : kBreatheType_Rising;
            }
        }
        else
        {
            mBreatheStepCntr++;
        }

        if (mBreatheType == kBreatheType_Rising)
        {
            if (mBreatheStepCntr == mBreatheStepNumb)
            {
                mLevel = mMaxLevel;
            }
            else if (mBreatheStepCntr == 0)
            {
                mLevel = mMinLevel;
            }
            else
            {
                mLevel += mBreatheStepLevel;
            }
        }
        else if (mBreatheType == kBreatheType_Falling)
        {
            if (mBreatheStepCntr == mBreatheStepNumb)
            {
                mLevel = mMinLevel;
            }
            else if (mBreatheStepCntr == 0)
            {
                mLevel = mMaxLevel;
            }
            else
            {
                mLevel -= mBreatheStepLevel;
            }
        }

        Set(true);
        StartBreatheTimer(kBreatheStepTimeMS);
    }
    // Update of Blink action
    else if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0)
    {
        Set(mState != kState_On ? true : false);
        StartBlinkTimer();
    }
    else
    {
        LOG_ERR("PWM LED update state is incorrect");
    }
}

void PWMDevice::StartBlinkTimer(void)
{
    k_timer_start(&mPwmLedTimer, K_MSEC(mState == kState_On ? mBlinkOnTimeMS : mBlinkOffTimeMS), K_NO_WAIT);
}

void PWMDevice::StartBreatheTimer(uint32_t stepTimeMS)
{
    k_timer_start(&mPwmLedTimer, K_MSEC(stepTimeMS), K_NO_WAIT);
}

void PWMDevice::ClearAction(void)
{
    k_timer_stop(&mPwmLedTimer);
    mBreatheBothDirection = false;
    mBreatheType          = kBreatheType_Invalid;
    mBreatheStepLevel     = 0;
    mBreatheStepNumb      = 0;
    mBlinkOnTimeMS        = 0;
    mBlinkOffTimeMS       = 0;
    mLevel                = mMaxLevel;
}

void PWMDevice::PwmLedTimerHandler(k_timer * timer)
{
    if (mActionBlinkStateUpdate_CB)
    {
        mActionBlinkStateUpdate_CB(timer);
    }
}
