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

#pragma once

#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/clusters/scenes-server/SceneTable.h>
#include <app/util/af-types.h>
#include <app/util/basic-types.h>
#include <platform/CHIPDeviceConfig.h>
#include <protocols/interaction_model/StatusCode.h>

/**********************************************************
 * Defines and Macros
 *********************************************************/

static constexpr chip::System::Clock::Milliseconds32 ON_OFF_UPDATE_TIME_MS = chip::System::Clock::Milliseconds32(100);

static constexpr uint16_t MIN_ON_OFF_TIME_VALUE = 1;
static constexpr uint16_t MAX_ON_OFF_TIME_VALUE = 0xFFFF;

/**
 * @brief
 *
 */
class OnOffServer
{
public:
    using Feature = chip::app::Clusters::OnOff::Feature;

    /**********************************************************
     * Functions Definitions
     *********************************************************/

    static OnOffServer & Instance();

    chip::scenes::SceneHandler * GetSceneHandler();

    bool offCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath);
    bool onCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath);
    bool toggleCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath);
    void initOnOffServer(chip::EndpointId endpoint);
    bool offWithEffectCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                              const chip::app::Clusters::OnOff::Commands::OffWithEffect::DecodableType & commandData);
    bool OnWithRecallGlobalSceneCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath);
    bool OnWithTimedOffCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                               const chip::app::Clusters::OnOff::Commands::OnWithTimedOff::DecodableType & commandData);
    void updateOnOffTimeCommand(chip::EndpointId endpoint);
    chip::Protocols::InteractionModel::Status getOnOffValue(chip::EndpointId endpoint, bool * currentOnOffValue);
    chip::Protocols::InteractionModel::Status setOnOffValue(chip::EndpointId endpoint, chip::CommandId command,
                                                            bool initiatedByLevelChange);
    chip::Protocols::InteractionModel::Status getOnOffValueForStartUp(chip::EndpointId endpoint, bool & onOffValueForStartUp);

    bool HasFeature(chip::EndpointId endpoint, Feature feature);
    inline bool SupportsLightingApplications(chip::EndpointId endpointId) { return HasFeature(endpointId, Feature::kLighting); }

    void cancelEndpointTimerCallback(chip::EndpointId endpoint);

private:
    /**********************************************************
     * Functions Definitions
     *********************************************************/

#ifndef IGNORE_ON_OFF_CLUSTER_START_UP_ON_OFF
    bool areStartUpOnOffServerAttributesNonVolatile(chip::EndpointId endpoint);
#endif
    EmberEventControl * getEventControl(chip::EndpointId endpoint, const chip::Span<EmberEventControl> & eventControlArray);
    EmberEventControl * configureEventControl(chip::EndpointId endpoint);

    uint32_t calculateNextWaitTimeMS(void);

    // Matter timer scheduling glue logic
    static void timerCallback(chip::System::Layer *, void * callbackContext);
    void scheduleTimerCallbackMs(EmberEventControl * control, uint32_t delayMs);
    void cancelEndpointTimerCallback(EmberEventControl * control);

    /**********************************************************
     * Attributes Declaration
     *********************************************************/

    static OnOffServer instance;
    chip::System::Clock::Timestamp nextDesiredOnWithTimedOffTimestamp;

    friend class DefaultOnOffSceneHandler;
};

struct OnOffEffect
{
    using OffWithEffectTriggerCommand = void (*)(OnOffEffect *);
    using EffectVariantType           = std::underlying_type_t<chip::app::Clusters::OnOff::DelayedAllOffEffectVariantEnum>;
    static_assert(
        std::is_same<EffectVariantType, std::underlying_type_t<chip::app::Clusters::OnOff::DyingLightEffectVariantEnum>>::value,
        "chip::app::Clusters::OnOff::DelayedAllOffEffectVariantEnum and "
        "chip::app::Clusters::OnOff::DyingLightEffectVariantEnum underlying types differ.");

    chip::EndpointId mEndpoint;
    OffWithEffectTriggerCommand mOffWithEffectTrigger = nullptr;
    chip::app::Clusters::OnOff::EffectIdentifierEnum mEffectIdentifier;
    EffectVariantType mEffectVariant;
    OnOffEffect * nextEffect = nullptr;

    OnOffEffect(
        chip::EndpointId endpoint, OffWithEffectTriggerCommand offWithEffectTrigger,
        chip::app::Clusters::OnOff::EffectIdentifierEnum effectIdentifier =
            chip::app::Clusters::OnOff::EffectIdentifierEnum::kDelayedAllOff,

        /*
         * effectVariant's type depends on the effectIdentifier so we don't know the type at compile time.
         * The assertion at the beginning of this method ensures the effect variants share the same base type.
         * Casting to the common base type for more flexibility since the type can be DelayedAllOffEffectVariantEnum or
         * DelayedAllOffEffectVariantEnum
         */
        EffectVariantType = chip::to_underlying(chip::app::Clusters::OnOff::DelayedAllOffEffectVariantEnum::kDelayedOffFastFade));
    ~OnOffEffect();

    bool hasNext() { return this->nextEffect != nullptr; }

    OnOffEffect * next() { return this->nextEffect; }

    void setNext(OnOffEffect * inst) { this->nextEffect = inst; }
};

/**********************************************************
 * Global
 *********************************************************/

/** @brief On/off Cluster Level Control Effect
 *
 * This is called by the framework when the on/off cluster initiates a command
 * that must effect a level control change. The implementation assumes that the
 * client will handle any effect on the On/Off Cluster.
 *
 * @param endpoint   Ver.: always
 * @param newValue   Ver.: always
 */
void emberAfOnOffClusterLevelControlEffectCallback(chip::EndpointId endpoint, bool newValue);

/**********************************************************
 * Callbacks
 *********************************************************/

/** @brief On/off Cluster Server Post Init
 *
 * Following resolution of the On/Off state at startup for this endpoint,
 * perform any additional initialization needed; e.g., synchronize hardware
 * state.
 *
 * @param endpoint Endpoint that is being initialized  Ver.: always
 */
void emberAfPluginOnOffClusterServerPostInitCallback(chip::EndpointId endpoint);

void onOffWaitTimeOffEventHandler(chip::EndpointId endpoint);
