
/*
 *
 *    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 "ClusterManager.h"
#include "Globals.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app/CommandHandler.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/util/basic-types.h>

#ifdef AUTO_PRINT_METRICS
#include <platform/cc13x2_26x2/DiagnosticDataProviderImpl.h>
#endif

using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::System;
using namespace ::chip::DeviceLayer;

constexpr uint32_t kIdentifyTimerDelayMS     = 250;
constexpr uint32_t kIdentifyTimerDelayPerSec = 4;
ClusterManager ClusterManager::sCluster;

#define ENDPOINT_ID_0 (0)
#define ENDPOINT_ID_1 (1)
#define ENDPOINT_ID_2 (2)

void OnIdentifyTriggerEffect(Identify * identify)
{
    switch (identify->mCurrentEffectIdentifier)
    {
    case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK:
        PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK");
        break;
    case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE:
        PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE");
        break;
    case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY:
        PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY");
        break;
    case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE:
        PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE");
        break;
    default:
        PLAT_LOG("No identifier effect");
        break;
    }
    return;
}

Identify gIdentify0 = {
    chip::EndpointId{ 0 },
    [](Identify *) { PLAT_LOG("onIdentifyStart"); },
    [](Identify *) { PLAT_LOG("onIdentifyStop"); },
    EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED,
    OnIdentifyTriggerEffect,
};

Identify gIdentify1 = {
    chip::EndpointId{ 1 },
    [](Identify *) { PLAT_LOG("onIdentifyStart"); },
    [](Identify *) { PLAT_LOG("onIdentifyStop"); },
    EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED,
    OnIdentifyTriggerEffect,
};

void ClusterManager::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
    using namespace app::Clusters::OnOff::Attributes;

    VerifyOrExit(attributeId == OnOff::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId));
    VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2,
                 PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId));

    // At this point we can assume that value points to a bool value.
    mEndpointOnOffState[endpointId - 1] = *value;
    endpointId == ENDPOINT_ID_1 ? LED_write(sAppGreenHandle, *value) : LED_write(sAppRedHandle, *value);

exit:
    return;
}

void ClusterManager::OnLevelControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
    using namespace app::Clusters::LevelControl::Attributes;

    bool onOffState    = mEndpointOnOffState[endpointId - 1];
    uint8_t brightness = onOffState ? *value : 0;

    VerifyOrExit(brightness > 0, PLAT_LOG("Brightness set to 0, ignoring"));
    VerifyOrExit(attributeId == CurrentLevel::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId));
    VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2,
                 PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId));

    if (brightness > LED_BRIGHTNESS_MAX)
    {
        brightness = LED_BRIGHTNESS_MAX;
    }

    endpointId == ENDPOINT_ID_1 ? LED_setOn(sAppGreenHandle, brightness) : LED_setOn(sAppRedHandle, brightness);

exit:
    return;
}

void ClusterManager::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
    using namespace app::Clusters::ColorControl::Attributes;

    VerifyOrExit(attributeId == CurrentHue::Id || attributeId == CurrentSaturation::Id,
                 PLAT_LOG("Unhandled AttributeId ID: '0x%04x", attributeId));
    VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2,
                 PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId));

    if (endpointId == ENDPOINT_ID_1)
    {
        uint8_t hue, saturation;
        if (attributeId == CurrentHue::Id)
        {
            hue = *value;
            /* Read Current Saturation value when Attribute change callback for HUE Attribute */
            CurrentSaturation::Get(endpointId, &saturation);
        }
        else
        {
            saturation = *value;
            /* Read Current Hue value when Attribute change callback for SATURATION Attribute */
            CurrentHue::Get(endpointId, &hue);
        }
        PLAT_LOG("Color Control triggered: Hue: %d Saturation: %d", hue, saturation);
    }
exit:
    return;
}

void ClusterManager::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint16_t size,
                                                           uint8_t * value)
{
    if (attributeId == app::Clusters::Identify::Attributes::IdentifyTime::Id && size == 2)
    {
        uint16_t identifyTime;
        memcpy(&identifyTime, value, size);
        if (identifyTime)
        {
            // Currently we have no separate indicator LEDs on each endpoints.
            // We are using LED1 for endpoint 0,1 and LED2 for endpoint 2
            if (endpointId == ENDPOINT_ID_2)
            {
                LED_startBlinking(sAppGreenHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec);
            }
            else
            {
                LED_startBlinking(sAppRedHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec);
            }
        }
        else
        {
            bool onOffState;
            endpointId == ENDPOINT_ID_0 ? onOffState = mEndpointOnOffState[0] : onOffState = mEndpointOnOffState[endpointId - 1];
            endpointId == ENDPOINT_ID_2 ? LED_write(sAppRedHandle, onOffState) : LED_write(sAppGreenHandle, onOffState);
        }
    }
}
