/*
 *
 *    Copyright (c) 2015-2017 Nest Labs, Inc.
 *    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.
 */

/**
 *    @file
 *      This file implements core functionality for the Nest Weave
 *      Address and Routing Module (WARM).
 *
 */

#include <Warm/Warm.h>
#include <Weave/Support/CodeUtils.h>

namespace nl {

namespace Weave {

namespace Warm {

// Internal Types

typedef enum {
        kInitStateNotInitialized = 0,   /**< This must be 0 so that mInitState's initial value will be kInitStateNotInitialized. */
        kInitStateInitialized
} InitState;

typedef enum {
    kPlatformActionExecutionContinue                      = false,  /**< continue action execution. */
    kPlatformActionExecutionSuspendForAsynchOpCompletion  = true    /**< suspend action execution for asynchronous operation to complete. */
} PlatformActionExecution;

typedef enum {
    kSystemFeatureTypeIsFabricMember           = (1 << 0),    /**< The System's Weave module            IS | IS NOT     a member of a fabric. */
    kSystemFeatureTypeWiFiConnected            = (1 << 1),    /**< The System's WiFi Interface          IS | IS NOT     connected. */
    kSystemFeatureTypeThreadConnected          = (1 << 2),    /**< The System's Thread Interface        IS | IS NOT     connected. */
    kSystemFeatureTypeThreadRoutingEnabled     = (1 << 3),    /**< The System's Thread Routing Feature  IS | IS NOT     enabled. */
    kSystemFeatureTypeBorderRoutingEnabled     = (1 << 4),    /**< The System's Border Routing Feature  IS | IS NOT     enabled. */
    kSystemFeatureTypeTunnelInterfaceEnabled   = (1 << 5),    /**< The System's Tunnel Interface        IS | IS NOT     enabled. */
    kSystemFeatureTypeTunnelState              = (1 << 6),    /**< The System's Tunnel Service          IS | IS NOT     established. */
    kSystemFeatureTypeCellularConnected        = (1 << 7),    /**< The System's Cellular Interface      IS | IS NOT     connected. */

    kSystemFeatureTypeMax                      = (1 << 16)    /**< DO NOT EXCEED; reserved to mark the max available bits. */
} SystemFeatureType;

typedef enum {
    kActionTypeWiFiHostAddress              = (1 << 0),   /**< Add | Remove the IP address for the WiFi Interface on the host's IP stack. */
    kActionTypeThreadHostAddress            = (1 << 1),   /**< Add | Remove the IP address for the Thread Interface on the host's IP stack. */
    kActionTypeThreadThreadAddress          = (1 << 2),   /**< Add | Remove the IP address for the Thread Interface on the Thread Module's IP stack. */
    kActionTypeLegacy6LoWPANHostAddress     = (1 << 3),   /**< Add | Remove the IP address for the Legacy 6LowPAN Interface on the host's IP stack. */
    kActionTypeLegacy6LoWPANThreadAddress   = (1 << 4),   /**< Add | Remove the IP address for the Legacy 6LowPAN Interface on the Thread Module's IP stack. */
    kActionTypeHostRouteThread              = (1 << 5),   /**< Add | Remove the IP route for the Thread Interface on the host's IP stack. */
    kActionTypeThreadAdvertisement          = (1 << 6),   /**< Start | Stop the route advertisement by the Thread Module. */
    kActionTypeThreadRoute                  = (1 << 7),   /**< Add | Remove the IP route on the Thread Module for Border Route support. */
    kActionTypeTunnelHostAddress            = (1 << 8),   /**< Add | Remove the IP address for the Tunnel Interface on the host's IP stack. */
    kActionTypeTunnelHostRoute              = (1 << 9),   /**< Add | Remove the IP route for the Tunnel Interface on the host's IP stack. */
    kActionTypeThreadRoutePriority          = (1 << 10),  /**< Change the Route Priority of the Thread Route on the Thread Module. */
    kActionTypeTunnelServiceRoute           = (1 << 11),  /**< Add | Remove the 64 bit IP route for Service subnet on the host's IP stack. */

    kActionTypeMax                          = (1 << 16)   /**< DO NOT EXCEED; reserved to mark the max available bits. */
} ActionType;

typedef uint16_t FlagsType;

typedef PlatformResult (* ActionFunction)(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId);

typedef struct
{
    FlagsType           mNecessaryActiveSystemFeatures; /**< Stores the System Features that that are pre-requisites for taking the affirmative form of the Action. */
    ActionType          mActionType;                    /**< The type of Action to which this Entry pertains. */
    ActionFunction      mAction;                        /**< A function to execute the Action. */
} ActionEntry;

typedef struct {
    InitState                                               mInitState;                    /**< Tracks State of the Module initialization. */
    const WeaveFabricState                                  *mFabricState;                 /**< Stores a fabric State. */
    uint64_t                                                mFabricId;                     /**< Stores the fabric id which was last joined */
    FlagsType                                               mSystemFeatureStateFlags;      /**< Tracks changes for System Feature State. */
    FlagsType                                               mActionStateFlags;             /**< Tracks State of Actions. */
#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL
    Profiles::WeaveTunnel::Platform::TunnelAvailabilityMode mTunnelRequestedAvailability;  /**< Stores the desired Tunnel availability. */
    Profiles::WeaveTunnel::Platform::TunnelAvailabilityMode mTunnelCurrentAvailability;    /**< Stores the configured Tunnel availability. */
#endif

    // the following members are used to support platform API's that return kPlatformResultInProgress
    volatile bool                                           mActionInProgress;             /**< Tracks whether or not an Action is in progress. */
    ActionType                                              mInProgressAction;             /**< Stores the type of Action that is in progress. */
    bool                                                    mInProgressActionState;        /**< Stores the desired State of the Action when the Action completes. */
} ModuleState;

// Prototypes

static void TakeActions(void);

// Global Variables

static ModuleState sState;
static WarmFabricStateDelegate sFabricStateDelegate;

// These may be unused depending on WARM_CONFIG_SUPPORT_XXX definitions
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING || \
    WARM_CONFIG_SUPPORT_WIFI || \
    WARM_CONFIG_SUPPORT_CELLULAR || \
    WARM_CONFIG_SUPPORT_THREAD_ROUTING || \
    WARM_CONFIG_SUPPORT_WEAVE_TUNNEL || \
    WARM_CONFIG_SUPPORT_BORDER_ROUTING
static const uint8_t kGlobalULAPrefixLength               = 48;
#endif
#if WARM_CONFIG_SUPPORT_WIFI
static const uint8_t kWiFiULAAddressPrefixLength          = 64;
#endif
static const uint8_t kThreadULAAddressPrefixLength        = 64;
#if WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK
static const uint8_t kLegacy6LoWPANULAAddressPrefixLength = 64;
#endif

#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL

static const uint8_t kTunnelAddressPrefixLength           = 128;

#if !WARM_CONFIG_ENABLE_FABRIC_DEFAULT_ROUTING
static const uint8_t kServiceULAAddressPrefixLength       = 64;
#endif // !WARM_CONFIG_ENABLE_FABRIC_DEFAULT_ROUTING

#endif // WARM_CONFIG_SUPPORT_WEAVE_TUNNEL

// Implementation

/**
 *  A static function that returns the current State of a specified action.
 *
 *  @note
 *    Refer to the definition of ActionType for
 *    the set of possible actions.
 *
 *  @param[in] inAction    The action type to query.
 *
 *  @return true if the action is Set, false otherwise.
 *
 */
static bool GetCurrentActionState(ActionType inAction)
{
    return (sState.mActionStateFlags & inAction) ? true : false;
}

/**
 *  A static function that sets the current State of a specified action.
 *
 *  @note
 *    Refer to the definition of ActionType for
 *    the set of possible actions.
 *
 *  @param[in] inAction    The action type to change.
 *  @param[in] inValue     The new State value to adopt.
 *
 */
static void SetCurrentActionState(ActionType inAction, bool inValue)
{
    const bool current = GetCurrentActionState(inAction);

    if (current != inValue) {

        if (inValue) {
            sState.mActionStateFlags |= inAction;
        } else {
            sState.mActionStateFlags &= ~inAction;
        }
    }
}

/**
 *  A static function that gets the current State of a System feature.
 *
 *  @note
 *    Refer to the definition of SystemFeatureType for
 *    the set of possible types.
 *
 *  @param[in] inSystemFeature    The System Feature to query.
 *
 *  @return true if the System Feature is enabled, false otherwise.
 *
 */
static inline bool GetSystemFeatureState(SystemFeatureType inSystemFeature)
{
    return (sState.mSystemFeatureStateFlags & inSystemFeature) ? true : false;
}

/**
 *  A static function that sets the current State of the System Feature.
 *
 *  @note
 *    Refer to the definition of SystemFeatureType for
 *    the set of possible System Features.
 *
 *  @param[in] inSystemFeature    The SystemFeature to set.
 *  @param[in] inValue            The new State value to adopt.
 *
 *  @return true if the System Feature was changed, false otherwise.
 *
 */
static bool SetSystemFeatureState(SystemFeatureType inSystemFeature, bool inValue)
{
    bool retval = false;
    const bool current = GetSystemFeatureState(inSystemFeature);

    if (current != inValue) {

        if (inValue) {
            sState.mSystemFeatureStateFlags |= inSystemFeature;
        } else {
            sState.mSystemFeatureStateFlags &= ~inSystemFeature;
        }

        retval = true;
    }

    return retval;
}

/**
 *  A static function that determines whether the specified action should be performed.
 *
 *  @brief
 *    This function examines the condition of the System Feature State flags and determines
 *    whether the specified action should be enabled or disabled.  The function then
 *    examines the current state of the action and if the action is not set to
 *    the value required by the System Feature's State, then the function returns true
 *    along with the desired action state in outActivate
 *
 *
 *  @param[in] inAction                         The action to be queried.
 *  @param[in] inNecessarySystemFeatureState    The State flags necessary for the action to be active.
 *  @param[out] outActivate                     The desired state of the action.
 *
 *  @return true if the action is not currently in the desired state, false otherwise.
 *
 */
static bool ShouldPerformAction(ActionType inAction, FlagsType inNecessarySystemFeatureState, bool &outActivate)
{
    bool retval = false;
    // Compare the necessary System Feature State flags to the current state of the action.
    const bool desiredActionState = (inNecessarySystemFeatureState == (sState.mSystemFeatureStateFlags & inNecessarySystemFeatureState));

#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL && WARM_CONFIG_SUPPORT_BORDER_ROUTING
    if (inAction == kActionTypeThreadRoutePriority)
    {
        if (desiredActionState &&
            sState.mTunnelRequestedAvailability != sState.mTunnelCurrentAvailability)
        {
            retval = true;  // instruct the caller to take action.
        }
    }
    else
#endif // WARM_CONFIG_SUPPORT_WEAVE_TUNNEL && WARM_CONFIG_SUPPORT_BORDER_ROUTING
    {
        if (GetCurrentActionState(inAction) != desiredActionState)
        {
            retval = true; // instruct the caller to take action.
            outActivate = desiredActionState; // provide the caller with the desired state of the action
        }
    }

    return retval;
}

/**
 *  A static function that records the result of a platform API Action call.
 *
 *  @brief
 *    This module makes requests to perform actions via platform specific API's.
 *    The API's are required to report the kPlatformResultSuccess|kPlatformResultFailure|kPlatformResultInProgress
 *    result of that action request.  This function records that result and returns
 *    true if the result is in-progress and further actions should be delayed.
 *
 *  @param[in] inResult         The platform API result.
 *  @param[in] inAction         The action that the platform API attempted.
 *  @param[in] inActionState    The new State of the action if the result was success.
 *
 *  @return true the platform API is asynchronously processing the request, false otherwise.
 *
 */
static PlatformActionExecution RecordPlatformResult(PlatformResult inResult, ActionType inAction, bool inActionState)
{
    PlatformActionExecution retval = kPlatformActionExecutionContinue;

    switch (inResult)
    {
        case kPlatformResultSuccess:
            SetCurrentActionState(inAction, inActionState);

#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL && WARM_CONFIG_SUPPORT_BORDER_ROUTING
            if ((inAction == kActionTypeThreadRoute && inActionState) ||
                (inAction == kActionTypeThreadRoutePriority))
            {
                sState.mTunnelCurrentAvailability = sState.mTunnelRequestedAvailability;
            }
#endif // WARM_CONFIG_SUPPORT_WEAVE_TUNNEL && WARM_CONFIG_SUPPORT_BORDER_ROUTING
            break;

        case kPlatformResultFailure:
            // return false to keep going. By not setting the ActionState the Action will be retried.
            // TODO: perhaps return true here to prevent continuation of actions on this iteration.
            break;

        case kPlatformResultInProgress:
            retval = kPlatformActionExecutionSuspendForAsynchOpCompletion; // instruct caller to stop executing actions.
            // record that an action is in progress and use this in ReportActionComplete()
            sState.mInProgressAction = inAction;
            sState.mInProgressActionState = inActionState;
            sState.mActionInProgress = true;
            break;
    }

    return retval;
}

/**
 *  A static function that Sets the System Feature state and notifies the platform
 *  that event state has changed.
 *
 *  @brief
 *    Called by the EventStateChange API's to perform the necessary reaction
 *    operations.
 *
 *  @param[in] inSystemFeatureType    The State that changed corresponding to the API called.
 *  @param[in] inState                The new value for the state.
 *
 */
static void SystemFeatureStateChangeHandler(SystemFeatureType inSystemFeatureType, bool inState)
{
    bool stateDidTransition;

    Platform::CriticalSectionEnter();
    {
        // If the state change is "becoming a new fabric member", update the copy of fabric id in local state.
        // Local copy of fabric id is used for calculating the addresses/routes to be added/remove to ensure
        // that the correct addresses/routes are removed when leaving the fabric (i.e., FabricState is cleared
        // and FabricState->FabricId is set to zero).
        if ((inSystemFeatureType == kSystemFeatureTypeIsFabricMember) && (inState == kInterfaceStateUp))
        {
            sState.mFabricId = sState.mFabricState->FabricId;
        }

        stateDidTransition = SetSystemFeatureState(inSystemFeatureType, inState);
    }
    Platform::CriticalSectionExit();

    if (stateDidTransition)
    {
        // Notify the platform layer that internal core State has changed and the platform
        // needs to call InvokeActions either synchronously or asynchronously as appropriate.
        Platform::RequestInvokeActions();
    }
}

/**
 *  A function called to announce a State change for the Weave Fabric feature.
 *
 *  @note
 *    While this function is similar to the other WARM APIs, it is used internally by WarmFabricStateDelegate class.
 *    This function is called when the device joins or leaves a Weave fabric. If the device boots
 *    up as a member of a fabric, this function should be called after Init() and after the fabricId has
 *    been stored in the Weave FabricState.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the system is a member of a Weave fabric, kInterfaceStateDown otherwise.
 *
 */
static void FabricStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeIsFabricMember, inState);
}

/**
 *  This method is invoked by WeaveFabricState when joining/creating a new fabric.
 *
 *  @param[in] fabricState   The WeaveFabricState which is changed.
 *  @param[in] newFabricId   The new fabric id.
 *
 */
void WarmFabricStateDelegate::DidJoinFabric(WeaveFabricState *fabricState, uint64_t newFabricId)
{
    FabricStateChange(kInterfaceStateUp);
}

/**
 *  This method is invoked by WeaveFabricState when leaving/clearing a fabric.
 *
 *  @param[in] fabricState   The WeaveFabricState which is changed.
 *  @param[in] oldFabricId   The old/previous fabric id.
 *
 */
void WarmFabricStateDelegate::DidLeaveFabric(WeaveFabricState *fabricState, uint64_t oldFabricId)
{
    FabricStateChange(kInterfaceStateDown);
}

/**
 *  A WARM API to perform one time module initialization.
 *
 *  @note
 *    It must be called prior to any other API calls.
 *
 *  @retval WEAVE_NO_ERROR               On successful initialization.
 *  @retval WEAVE_ERROR_INCORRECT_STATE  When Init is called more than once.
 *  @retval other                        Error code otherwise.
 *
 */
WEAVE_ERROR Init(WeaveFabricState &inFabricState)
{
    WEAVE_ERROR err;

    if (sState.mInitState != kInitStateNotInitialized)
    {
        return WEAVE_ERROR_INCORRECT_STATE;
    }

    sState.mSystemFeatureStateFlags = 0;
    sState.mActionStateFlags        = 0;
    sState.mActionInProgress        = false;
    sState.mFabricState             = &inFabricState;

    err = Platform::Init(&sFabricStateDelegate);
    SuccessOrExit(err);

    // Set the WeaveFabricState delegate first.
    inFabricState.SetDelegate(&sFabricStateDelegate);

    Platform::CriticalSectionEnter();
    {
        // Then update/inform WARM of the current fabric state. This should be done within
        // the critical section to protect against race situation caused by delegate callbacks
        // (which can be invoked from another task/process context)
        FabricStateChange((inFabricState.FabricId != 0)?  kInterfaceStateUp : kInterfaceStateDown);
    }
    Platform::CriticalSectionExit();

    sState.mInitState = kInitStateInitialized;

exit:
    return err;
}

/**
 * A WARM API to perform a clean shutdown.
 *
 * @note
 *   It must be called during shutdown of weave stack.
 *
 * @param[in]  inFabricState    A reference to a valid WeaveFabricState.
 */
void Shutdown(WeaveFabricState &inFabricState)
{
    sState.mInitState = kInitStateNotInitialized;
    inFabricState.SetDelegate(NULL);
}

/**
 *  A WARM API to acquire a ULA for a specified interface type.
 *
 *  @note
 *    Platform code should call this only after WARM has been initialized. Calling this API
 *    prior to initialization will result in an error.
 *
 *  @param[in] inInterfaceType    The type of interface for which a ULA is desired.
 *  @param[out] outAddress        An address object used to hold the resulting ULA.
 *
 *  @retval WEAVE_NO_ERROR                On success.
 *  @retval WEAVE_ERROR_INCORRECT_STATE   If this API is called while WARM is
 *                                        not a member of a Fabric.
 *  @retval WEAVE_ERROR_INVALID_ARGUMENT  If this API is called with an invalid Interface Type.
 *
 */
WEAVE_ERROR GetULA(InterfaceType inInterfaceType, Inet::IPAddress &outAddress)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint64_t    globalId;
    uint64_t    interfaceId;
    uint16_t    subnet;

    switch (inInterfaceType)
    {
        case kInterfaceTypeLegacy6LoWPAN:
            subnet = nl::Weave::kWeaveSubnetId_ThreadAlarm;
            break;

        case kInterfaceTypeThread:
            subnet = nl::Weave::kWeaveSubnetId_ThreadMesh;
            break;

        case kInterfaceTypeWiFi:
            subnet = nl::Weave::kWeaveSubnetId_PrimaryWiFi;
            break;

        default:
            err = WEAVE_ERROR_INVALID_ARGUMENT;
            goto exit;
    }

    Platform::CriticalSectionEnter();
    {
        if (GetSystemFeatureState(kSystemFeatureTypeIsFabricMember))
        {
            globalId = nl::Weave::WeaveFabricIdToIPv6GlobalId(sState.mFabricId);
            interfaceId = nl::Weave::WeaveNodeIdToIPv6InterfaceId(sState.mFabricState->LocalNodeId);
        } else {
            err = WEAVE_ERROR_INCORRECT_STATE;
        }
    }
    Platform::CriticalSectionExit();

    SuccessOrExit(err);

    outAddress = nl::Inet::IPAddress::MakeULA(globalId, subnet, interfaceId);

exit:
    return err;
}

/**
 *  A WARM API to acquire the FabricState object that was provided to Warm during Init.
 *
 *  @note
 *    Platform code should call this only after WARM has been initialized. Calling this API
 *    prior to initialization will result in an error.
 *
 *  @param[out] outFabricState        A pointer reference to a fabricState object.
 *
 *  @retval WEAVE_NO_ERROR                On success.
 *  @retval WEAVE_ERROR_INCORRECT_STATE   If this API is called before WARM
 *                                        has been initialized.
 *
 */
WEAVE_ERROR GetFabricState(const WeaveFabricState *&outFabricState)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (sState.mInitState != kInitStateInitialized)
    {
        err = WEAVE_ERROR_INCORRECT_STATE;
    }

    SuccessOrExit(err);

    outFabricState = sState.mFabricState;

exit:
    return err;
}

/**
 *  A WARM API called by a dedicated task to perform various platform API actions.
 *
 *  @brief
 *    This represents the entry point to perform the actions necessary which will satisfy
 *    the current System State.  If for example the Thread stack transitioned from
 *    disabled to enabled, then this function would make the necessary platform calls
 *    to assign the thread host address etc.  This function should be called by platform
 *    code only in response to a Warm call to RequestInvokeActions.  Calling InvokeActions
 *    will result in one or more calls to nl::Warm::Platform API's.
 *    Developers should therefore implement RequestInvokeActions and the caller of
 *    InvokeActions() appropriately. It might be appropriate for RequestInvokeActions to post
 *    an event to the task which would call InvokeActions() for example.  Conversely, if the system
 *    is single threaded, then RequestInvokeActions could be implemented to call InvokeActions()
 *    directly.
 *
 */
void InvokeActions(void)
{
    Platform::CriticalSectionEnter();
    {
        if (!sState.mActionInProgress)
        {
            // this represents what should be the one-and-only call to TakeActions().
            TakeActions();
        }
    }
    Platform::CriticalSectionExit();
}

/**
 *  A WARM API called to announce the completion of a previous asynchronous platform API call.
 *
 *  @brief
 *    It is assumed that platform action API's may need to perform asynchronous operations.
 *    If this is true then the platform API will return kPlatformResultInProgress.
 *    When this happens new Address and Routing Actions will be suspended until the system
 *    calls ReportActionComplete to announce the completion of the operation.
 *
 *  @param[in]  inResult    The result of the pending action. must be one of: {kPlatformResultSuccess | kPlatformResultFailure}
 *
 */
void ReportActionComplete(PlatformResult inResult)
{
    VerifyOrExit(((inResult != kPlatformResultInProgress) && (sState.mActionInProgress)), (void)0);

    Platform::CriticalSectionEnter();
    {
        RecordPlatformResult(inResult, sState.mInProgressAction, sState.mInProgressActionState);
        sState.mActionInProgress = false;
    }
    Platform::CriticalSectionExit();

    Platform::RequestInvokeActions();

exit:
    return;
}

#if WARM_CONFIG_SUPPORT_CELLULAR

/**
 *  A WARM API called to announce a State change for the Cellular interface.
 *
 *  @note
 *    Platform code should call this function when the Cellular interface transitions between up <-> down.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the Cellular interface is up, kInterfaceStateDown otherwise.
 *
 */
void CellularInterfaceStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeCellularConnected, inState);
}

#endif // WARM_CONFIG_SUPPORT_CELLULAR

#if WARM_CONFIG_SUPPORT_WIFI

/**
 *  One of the Action methods. Sets the Host Address for the WiFi Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostAddress().
 *
 */
static PlatformResult WiFiHostAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, nl::Weave::kWeaveSubnetId_PrimaryWiFi, inInterfaceId);

    return Platform::AddRemoveHostAddress(kInterfaceTypeWiFi, address, kWiFiULAAddressPrefixLength, inActivate);
}

/**
 *  A WARM API called to announce a State change for the WiFi interface.
 *
 *  @note
 *    Platform code should call this function when the WiFi interface transitions between up <-> down.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the WiFi interface is up, kInterfaceStateDown otherwise.
 *
 */
void WiFiInterfaceStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeWiFiConnected, inState);
}

#endif // WARM_CONFIG_SUPPORT_WIFI

/**
 *  A utility to construct a 48 bit prefix from a globalID.
 *
 *  @param[in] inGlobalID       A reference to the Weave Global ID.
 *  @param[out] outPrefix       The Prefix to initialize.
 *
 */
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING || \
    WARM_CONFIG_SUPPORT_WIFI || \
    WARM_CONFIG_SUPPORT_CELLULAR || \
    WARM_CONFIG_SUPPORT_WEAVE_TUNNEL || \
    WARM_CONFIG_SUPPORT_BORDER_ROUTING
static void MakePrefix(const uint64_t &inGlobalID, const uint16_t subnetId, const uint8_t inPrefixLen,
                       Inet::IPPrefix &outPrefix)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalID, subnetId, 0);

    outPrefix.IPAddr = address;
    outPrefix.Length = inPrefixLen;
}
#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING || WARM_CONFIG_SUPPORT_WIFI...

#if WARM_CONFIG_SUPPORT_THREAD

/**
 *  One of the Action methods. Sets the Host Address for the Thread Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostAddress().
 *
 */
static PlatformResult ThreadHostAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, nl::Weave::kWeaveSubnetId_ThreadMesh, inInterfaceId);

    return Platform::AddRemoveHostAddress(kInterfaceTypeThread, address, kThreadULAAddressPrefixLength, inActivate);
}

/**
 *  One of the Action methods. Sets the Thread Address for the Thread Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::ThreadAddress().
 *
 */
static PlatformResult ThreadThreadAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, nl::Weave::kWeaveSubnetId_ThreadMesh, inInterfaceId);

    return Platform::AddRemoveThreadAddress(kInterfaceTypeThread, address, inActivate);
}

/**
 *  One of the Action methods. Sets the Host Route for the Thread Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostRoute().
 *
 */
static PlatformResult ThreadHostRouteAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    Inet::IPPrefix prefix;
    PlatformResult result = kPlatformResultSuccess;

#if WARM_CONFIG_SUPPORT_WIFI || WARM_CONFIG_SUPPORT_CELLULAR

#if WARM_CONFIG_ENABLE_FABRIC_DEFAULT_ROUTING
    MakePrefix(inGlobalId, 0, kGlobalULAPrefixLength, prefix);
#else
    MakePrefix(inGlobalId, nl::Weave::kWeaveSubnetId_Service, kServiceULAAddressPrefixLength, prefix);
#endif // WARM_CONFIG_ENABLE_FABRIC_DEFAULT_ROUTING

#if WARM_CONFIG_ENABLE_BACKUP_ROUTING_OVER_THREAD
    result = Platform::AddRemoveHostRoute(kInterfaceTypeThread, prefix, kRoutePriorityLow, inActivate);
#endif // WARM_CONFIG_ENABLE_BACKUP_ROUTING_OVER_THREAD

#else

    prefix = prefix.Zero;
    prefix.Length = 0;

    result = Platform::AddRemoveHostRoute(kInterfaceTypeThread, prefix, kRoutePriorityLow, inActivate);
#endif // WARM_CONFIG_SUPPORT_WIFI || WARM_CONFIG_SUPPORT_CELLULAR

    return result;
}

/**
 *  A WARM API called to announce a State change for the Thread interface.
 *
 *  @note
 *    Platform code should call this function when the Thread interface transitions between up <-> down.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the Thread interface is up, kInterfaceStateDown otherwise.
 *
 */
void ThreadInterfaceStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeThreadConnected, inState);
}

#endif // WARM_CONFIG_SUPPORT_THREAD

#if WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK

/**
 *  One of the Action methods. Sets the Host Address for the Legacy Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostAddress().
 *
 */
static PlatformResult LegacyHostAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, nl::Weave::kWeaveSubnetId_ThreadAlarm, inInterfaceId);

    return Platform::AddRemoveHostAddress(kInterfaceTypeLegacy6LoWPAN, address, kLegacy6LoWPANULAAddressPrefixLength, inActivate);
}

/**
 *  One of the Action methods. Sets the Thread Address for the Legacy 6LoWPAN Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::ThreadAddress().
 *
 */
static PlatformResult LegacyThreadAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, nl::Weave::kWeaveSubnetId_ThreadAlarm, inInterfaceId);

    return Platform::AddRemoveThreadAddress(kInterfaceTypeLegacy6LoWPAN, address, inActivate);
}

#endif // WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK

#if WARM_CONFIG_SUPPORT_THREAD_ROUTING

/**
 *  One of the Action methods. Sets the Thread Advertisement State
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::ThreadAdvertisement().
 *
 */
static PlatformResult ThreadAdvertisementAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    Inet::IPPrefix prefix;

    MakePrefix(inGlobalId, kWeaveSubnetId_ThreadMesh, kThreadULAAddressPrefixLength, prefix);

    return Platform::StartStopThreadAdvertisement(kInterfaceTypeThread, prefix, inActivate);
}

/**
 *  A WARM API called to announce a State change for the Thread Routing feature.
 *
 *  @note
 *    Platform code should call this function when the ThreadRouting feature transitions between active <-> deactive.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the Thread routing feature is up, kInterfaceStateDown otherwise.
 *
 */
void ThreadRoutingStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeThreadRoutingEnabled, inState);
}

#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING

#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL

/**
 *  One of the Action methods. Sets the HostAddress for the Tunnel Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostAddress().
 *
 */
static PlatformResult TunnelHostAddressAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    // Prioritize using the Thread address over the WiFi address in order to improve connectivity
    // in cases where the WiFi network is unavailable and another path exists to the fabic.  See
    // the Weave Device Local Addressing and Routing Behavior document for more detail.
#if WARM_CONFIG_SUPPORT_THREAD
    const uint16_t kTunnelSubnet = nl::Weave::kWeaveSubnetId_ThreadMesh;
#else
    const uint16_t kTunnelSubnet = nl::Weave::kWeaveSubnetId_PrimaryWiFi;
#endif

    const Inet::IPAddress address = nl::Inet::IPAddress::MakeULA(inGlobalId, kTunnelSubnet, inInterfaceId);

    return Platform::AddRemoveHostAddress(kInterfaceTypeTunnel, address, kTunnelAddressPrefixLength, inActivate);
}

/**
 *  One of the Action methods. Sets the HostRoute for the Tunnel Interface.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::HostRoute().
 *
 */
static PlatformResult TunnelHostRouteAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    Inet::IPPrefix prefix;

#if WARM_CONFIG_ENABLE_FABRIC_DEFAULT_ROUTING
    MakePrefix(inGlobalId, 0, kGlobalULAPrefixLength, prefix);
#else
    MakePrefix(inGlobalId, nl::Weave::kWeaveSubnetId_Service, kServiceULAAddressPrefixLength, prefix);
#endif

    return Platform::AddRemoveHostRoute(kInterfaceTypeTunnel, prefix, kRoutePriorityMedium, inActivate);
}

/**
 *  A WARM API called to announce a State change for the Weave Tunnel interface.
 *
 *  @note
 *    This WARM API is called by the Weave Tunnel Agent Platform API's. The Platform code
 *    should not call this API as it would for other API's.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState           kInterfaceStateUp if the Weave Tunnel interface is up, kInterfaceStateDown otherwise.
 *
 */
static void TunnelInterfaceStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeTunnelInterfaceEnabled, inState);
}

/**
 *  A WARM API called to announce a State change for the Weave Tunnel interface.
 *
 *  @note
 *    This WARM API is called by the Weave Tunnel Agent Platform API's. The Platform code
 *    should not call this API as it would for other API's.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState           kInterfaceStateUp if the Weave Tunnel Service is established, kInterfaceStateDown otherwise.
 *  @param[in] inAvailability    The availability status to be used later in configuring the tunnel.
 *
 */
static void TunnelServiceStateChange(InterfaceState inState, nl::Weave::Profiles::WeaveTunnel::Platform::TunnelAvailabilityMode inAvailability)
{
    if (inState)
    {
        Platform::CriticalSectionEnter();
        {
            sState.mTunnelRequestedAvailability = inAvailability;
        }
        Platform::CriticalSectionExit();
    }

    SystemFeatureStateChangeHandler(kSystemFeatureTypeTunnelState, inState);
}

/**
 *  A WARM API called to update the priority of the Tunnel Service.
 *
 *  @note
 *    This WARM API is called by the Weave Tunnel Agent Platform API's. The Platform code
 *    should not call this API as it would for other API's.  If this call results
 *    in a change of State WARM will call RequestInvokeActions
 *
 *  @param[in] inAvailability    The new value for the tunnel availability status.
 *
 */
static void TunnelPriorityStateChange(nl::Weave::Profiles::WeaveTunnel::Platform::TunnelAvailabilityMode inAvailability)
{
    bool notify = false;

    Platform::CriticalSectionEnter();
    {
        if (GetSystemFeatureState(kSystemFeatureTypeTunnelState) &&
            sState.mTunnelRequestedAvailability != inAvailability)
        {
            sState.mTunnelRequestedAvailability = inAvailability;
            notify = true;
        }
    }
    Platform::CriticalSectionExit();

    if (notify)
    {
        Platform::RequestInvokeActions();
    }
}

}; // namespace Warm

// Implementation of WeaveTunnelAgent Platform API's

namespace Profiles {
namespace WeaveTunnel {
namespace Platform {

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to announce the tunnel interface is enabled.
 *
 *  @param[in] tunIf    The InterfaceId for the tunnel Interface.  Not used in this implementation.
 *
 */
void TunnelInterfaceUp(InterfaceId tunIf)
{
    (void)tunIf;

    Warm::TunnelInterfaceStateChange(Warm::kInterfaceStateUp);
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to announce the tunnel interface is disabled.
 *
 *  @param[in] tunIf    The InterfaceId for the tunnel Interface.  Not used in this implementation.
 *
 */
void TunnelInterfaceDown(InterfaceId tunIf)
{
    (void)tunIf;

    Warm::TunnelInterfaceStateChange(Warm::kInterfaceStateDown);
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to announce a tunnel interface connection.
 *
 *  @param[in] tunIf    The InterfaceId for the tunnel Interface.  Not used in this implementation.
 *  @param[in] tunMode  The initial tunnel availability mode to be adopted by Warm.
 *
 */
void ServiceTunnelEstablished(InterfaceId tunIf, TunnelAvailabilityMode tunMode)
{
    (void)tunIf;

    Warm::TunnelServiceStateChange(Warm::kInterfaceStateUp, tunMode);
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to announce a tunnel interface disconnection.
 *
 *  @param[in] tunIf    The InterfaceId for the tunnel Interface.  Not used in this implementation.
 *
 */
void ServiceTunnelDisconnected(InterfaceId tunIf)
{
    (void)tunIf;

    Warm::TunnelServiceStateChange(Warm::kInterfaceStateDown, Warm::sState.mTunnelRequestedAvailability);
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to announce a Tunnel availability change.
 *
 *  @param[in] tunIf    The InterfaceId for the tunnel Interface.  Not used in this implementation.
 *  @param[in] tunMode  The new tunnel availability mode to be adopted by Warm.
 *
 */
void ServiceTunnelModeChange(InterfaceId tunIf, TunnelAvailabilityMode tunMode)
{
    (void)tunIf;

    Warm::TunnelPriorityStateChange(tunMode);
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to enable Border Routing
 *  through Warm.
 *
 */
void EnableBorderRouting(void)
{
#if WARM_CONFIG_SUPPORT_BORDER_ROUTING
    Warm::BorderRouterStateChange(Warm::kInterfaceStateUp);
#endif // WARM_CONFIG_SUPPORT_BORDER_ROUTING
}

/**
 *  A TunnelAgent Platform API implementation used by the Tunnel Agent to disable Border Routing
 *  through Warm.
 *
 */
void DisableBorderRouting(void)
{
#if WARM_CONFIG_SUPPORT_BORDER_ROUTING
    Warm::BorderRouterStateChange(Warm::kInterfaceStateDown);
#endif // WARM_CONFIG_SUPPORT_BORDER_ROUTING
}

}; // namespace Platform

}; // namespace WeaveTunnel

}; // namespace Profiles

namespace Warm {

#endif // WARM_CONFIG_SUPPORT_WEAVE_TUNNEL

#if WARM_CONFIG_SUPPORT_BORDER_ROUTING

/**
 *  A WARM API called to announce a State change for the Border router feature.
 *
 *  @note
 *    Platform code should call this when the Border Routing feature transitions between active <-> deactive.
 *    If this call results in a change of State WARM will call RequestInvokeActions.
 *
 *  @param[in] inState    kInterfaceStateUp if the Border router feature is up, kInterfaceStateDown otherwise.
 *
 */
void BorderRouterStateChange(InterfaceState inState)
{
    SystemFeatureStateChangeHandler(kSystemFeatureTypeBorderRoutingEnabled, inState);
}

/**
 *  A static function that returns a mapping from TunnelAvailability to RoutePriority
 *
 *  @param[in] inAvailability         The Weave tunnel availability mode.
 *
 *  @return The priority mapped value.
 *
 */
static RoutePriority MapAvailabilityToPriority(Profiles::WeaveTunnel::Platform::TunnelAvailabilityMode inAvailability)
{
    RoutePriority retval = kRoutePriorityMedium;

    switch (inAvailability)
    {
        case Profiles::WeaveTunnel::Platform::kMode_Primary:
        case Profiles::WeaveTunnel::Platform::kMode_PrimaryAndBackup:
            retval = kRoutePriorityMedium;
            break;

        case Profiles::WeaveTunnel::Platform::kMode_BackupOnly:
            retval = kRoutePriorityLow;
            break;
    }

    return retval;
}

/**
 *  One of the Action methods. Sets the Thread Route for the Thread Stack.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::ThreadRoute().
 *
 */
static PlatformResult ThreadThreadRouteAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    Inet::IPPrefix prefix;

    MakePrefix(inGlobalId, 0, kGlobalULAPrefixLength, prefix);

    return Platform::AddRemoveThreadRoute(kInterfaceTypeThread, prefix, MapAvailabilityToPriority(sState.mTunnelRequestedAvailability), inActivate);

}

/**
 *  One of the Action methods. Sets the Thread Route Priority based on the Tunnel Availability.
 *
 *  @param[in] inAction         The action type.
 *  @param[in] inActivate       The desired State true == activate, false == deactivate.
 *  @param[in] inGlobalId       A reference to the Weave Global ID if it's necessary to calculate an address.
 *  @param[in] inInterfaceId    A reference to the device's interface ID if it's necessary to calculate an address.
 *
 *  @return Forwards the result from Platform::ThreadRoutePriority().
 *
 */
static PlatformResult ThreadRoutePriorityAction(ActionType inAction, bool inActivate, const uint64_t &inGlobalId, const uint64_t &inInterfaceId)
{
    Inet::IPPrefix prefix;

    MakePrefix(inGlobalId, 0, kGlobalULAPrefixLength, prefix);

    return Platform::SetThreadRoutePriority(kInterfaceTypeThread, prefix, MapAvailabilityToPriority(sState.mTunnelRequestedAvailability));

}

#endif // WARM_CONFIG_SUPPORT_BORDER_ROUTING

/**
 *  A static function that tests the State of each action and makes a platform API
 *  call to change the action State if necessary.
 *
 *  @brief
 *    This function uses ShouldPerformAction() to determine if an action state
 *    needs to be changed/taken.  If ShouldPerformAction() returns true the function
 *    will call the appropriate action API to perform the action in order to put
 *    it in the desired State.  The result of the action API call is passed
 *    into RecordPlatformResult() and if that function returns true, the execution
 *    of this function is terminated.
 *
 */
static void TakeActions(void)
{
    static const ActionEntry kActions[] =
    {
    // TODO: Order of operations could be important here.  If it is found that a specific order of operations must be
    // maintained, then this structure will need to be re-factored.  The current implementation has a single fixed order
    // which may not be adequate.
#if WARM_CONFIG_SUPPORT_WIFI
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeWiFiConnected ),
            kActionTypeWiFiHostAddress,
            WiFiHostAddressAction
        },
#endif // WARM_CONFIG_SUPPORT_WIFI
#if WARM_CONFIG_SUPPORT_THREAD
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected ),
            kActionTypeThreadHostAddress,
            ThreadHostAddressAction
        },
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected ),
            kActionTypeThreadThreadAddress,
            ThreadThreadAddressAction
        },
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected ),
            kActionTypeHostRouteThread,
            ThreadHostRouteAction
        },
#endif // WARM_CONFIG_SUPPORT_THREAD
#if WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected ),
            kActionTypeLegacy6LoWPANHostAddress,
            LegacyHostAddressAction
        },
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected ),
            kActionTypeLegacy6LoWPANThreadAddress,
            LegacyThreadAddressAction
        },
#endif // WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected |
              kSystemFeatureTypeThreadRoutingEnabled ),
            kActionTypeThreadAdvertisement,
            ThreadAdvertisementAction
        },
#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING
#if WARM_CONFIG_SUPPORT_BORDER_ROUTING
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected |
              kSystemFeatureTypeThreadRoutingEnabled |
              kSystemFeatureTypeTunnelInterfaceEnabled |
              kSystemFeatureTypeBorderRoutingEnabled |
              kSystemFeatureTypeTunnelState ),
            kActionTypeThreadRoute,
            ThreadThreadRouteAction
        },
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeThreadConnected |
              kSystemFeatureTypeThreadRoutingEnabled |
              kSystemFeatureTypeTunnelInterfaceEnabled |
              kSystemFeatureTypeBorderRoutingEnabled |
              kSystemFeatureTypeTunnelState ),
            kActionTypeThreadRoutePriority,
            ThreadRoutePriorityAction
        },
#endif // WARM_CONFIG_SUPPORT_BORDER_ROUTING
#if WARM_CONFIG_SUPPORT_WEAVE_TUNNEL
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeTunnelInterfaceEnabled ),
            kActionTypeTunnelHostAddress,
            TunnelHostAddressAction
        },
        {
            ( kSystemFeatureTypeIsFabricMember |
              kSystemFeatureTypeTunnelInterfaceEnabled |
              kSystemFeatureTypeTunnelState),
            kActionTypeTunnelHostRoute,
            TunnelHostRouteAction
        },
#endif // WARM_CONFIG_SUPPORT_WEAVE_TUNNEL
    };

    bool activate = false;
    PlatformResult platformResult;
    const uint64_t globalId = nl::Weave::WeaveFabricIdToIPv6GlobalId(sState.mFabricId);
    const uint64_t interfaceId = nl::Weave::WeaveNodeIdToIPv6InterfaceId(sState.mFabricState->LocalNodeId);
    ActionType theActionType;

    for (size_t i = 0 ; i < sizeof(kActions) / sizeof(kActions[0]) ; i++)
    {
        theActionType = kActions[i].mActionType;

        if (ShouldPerformAction(theActionType, kActions[i].mNecessaryActiveSystemFeatures, activate))
        {
            platformResult = kActions[i].mAction(theActionType, activate, globalId, interfaceId);

            if (kPlatformActionExecutionContinue != RecordPlatformResult(platformResult, theActionType, activate))
            {
                break;
            }
        }
    }
}

}; // namespace Warm

}; // namespace Weave

}; // namespace nl
