/*
 *  Copyright (c) 2019, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for MLE types and constants.
 */

#ifndef MLE_TYPES_HPP_
#define MLE_TYPES_HPP_

#include "openthread-core-config.h"

#include <limits.h>
#include <stdint.h>
#include <string.h>

#include <openthread/thread.h>
#if OPENTHREAD_FTD
#include <openthread/thread_ftd.h>
#endif

#include "common/array.hpp"
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/code_utils.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "common/string.hpp"
#include "mac/mac_types.hpp"
#include "meshcop/extended_panid.hpp"
#include "net/ip6_address.hpp"
#include "thread/network_data_types.hpp"

namespace ot {

class Message;

namespace Mle {

/**
 * @addtogroup core-mle-core
 *
 * @brief
 *   This module includes definition for MLE types and constants.
 *
 * @{
 *
 */

constexpr uint16_t kUdpPort = 19788; ///< MLE UDP Port

constexpr uint16_t kMaxChildren     = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN; ///< Maximum number of children
constexpr uint16_t kMinChildId      = 1;                                  ///< Minimum Child ID
constexpr uint16_t kMaxChildId      = 511;                                ///< Maximum Child ID
constexpr uint8_t  kMaxRouters      = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS;  ///< Maximum number of routers
constexpr uint8_t  kMaxRouterId     = OT_NETWORK_MAX_ROUTER_ID;           ///< Max Router ID
constexpr uint8_t  kInvalidRouterId = kMaxRouterId + 1;                   ///< Value indicating invalid Router ID
constexpr uint8_t  kRouterIdOffset  = 10;                                 ///< Bit offset of router ID in RLOC16
constexpr uint16_t kInvalidRloc16   = Mac::kShortAddrInvalid;             ///< Invalid RLOC16.

#if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
constexpr uint8_t kMaxRouteCost = 127; ///< Maximum path cost
#else
constexpr uint8_t kMaxRouteCost = 16; ///< Maximum path cost
#endif

constexpr uint8_t kMeshLocalPrefixContextId = 0; ///< Reserved 6lowpan context ID for Mesh Local Prefix

/**
 * Number of consecutive tx failures to child (with no-ack error) to consider child-parent link broken.
 *
 */
constexpr uint8_t kFailedChildTransmissions = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS;

/**
 * Threshold to accept a router upgrade request with reason `kBorderRouterRequest` (number of BRs acting as router in
 * Network Data).
 *
 */
constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;

/**
 * Represents a Thread device role.
 *
 */
enum DeviceRole : uint8_t
{
    kRoleDisabled = OT_DEVICE_ROLE_DISABLED, ///< The Thread stack is disabled.
    kRoleDetached = OT_DEVICE_ROLE_DETACHED, ///< Not currently participating in a Thread network/partition.
    kRoleChild    = OT_DEVICE_ROLE_CHILD,    ///< The Thread Child role.
    kRoleRouter   = OT_DEVICE_ROLE_ROUTER,   ///< The Thread Router role.
    kRoleLeader   = OT_DEVICE_ROLE_LEADER,   ///< The Thread Leader role.
};

constexpr uint16_t kAloc16Leader                      = 0xfc00;
constexpr uint16_t kAloc16DhcpAgentStart              = 0xfc01;
constexpr uint16_t kAloc16DhcpAgentEnd                = 0xfc0f;
constexpr uint16_t kAloc16ServiceStart                = 0xfc10;
constexpr uint16_t kAloc16ServiceEnd                  = 0xfc2f;
constexpr uint16_t kAloc16CommissionerStart           = 0xfc30;
constexpr uint16_t kAloc16CommissionerEnd             = 0xfc37;
constexpr uint16_t kAloc16BackboneRouterPrimary       = 0xfc38;
constexpr uint16_t kAloc16CommissionerMask            = 0x0007;
constexpr uint16_t kAloc16NeighborDiscoveryAgentStart = 0xfc40;
constexpr uint16_t kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e;

/**
 * Specifies the leader role start mode.
 *
 * The start mode indicates whether device is starting normally as leader or restoring its role after reset.
 *
 */
enum LeaderStartMode : uint8_t
{
    kStartingAsLeader,              ///< Starting as leader normally.
    kRestoringLeaderRoleAfterReset, ///< Restoring leader role after reset.
};

/**
 * Represents a MLE device mode.
 *
 */
class DeviceMode : public Equatable<DeviceMode>
{
public:
    static constexpr uint8_t kModeRxOnWhenIdle     = 1 << 3; ///< If to keep receiver on when not transmitting.
    static constexpr uint8_t kModeReserved         = 1 << 2; ///< Set on transmission, ignore on reception.
    static constexpr uint8_t kModeFullThreadDevice = 1 << 1; ///< If the device is an FTD.
    static constexpr uint8_t kModeFullNetworkData  = 1 << 0; ///< If the device requires the full Network Data.

    static constexpr uint16_t kInfoStringSize = 45; ///< String buffer size used for `ToString()`.

    /**
     * Defines the fixed-length `String` object returned from `ToString()`.
     *
     */
    typedef String<kInfoStringSize> InfoString;

    /**
     *  This structure represents an MLE Mode configuration.
     *
     */
    typedef otLinkModeConfig ModeConfig;

    /**
     * This is the default constructor for `DeviceMode` object.
     *
     */
    DeviceMode(void) = default;

    /**
     * Initializes a `DeviceMode` object from a given mode TLV bitmask.
     *
     * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
     *
     */
    explicit DeviceMode(uint8_t aMode) { Set(aMode); }

    /**
     * Initializes a `DeviceMode` object from a given mode configuration structure.
     *
     * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
     *
     */
    explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }

    /**
     * Gets the device mode as a mode TLV bitmask.
     *
     * @returns The device mode as a mode TLV bitmask.
     *
     */
    uint8_t Get(void) const { return mMode; }

    /**
     * Sets the device mode from a given mode TLV bitmask.
     *
     * @param[in] aMode   A mode TLV bitmask.
     *
     */
    void Set(uint8_t aMode) { mMode = aMode | kModeReserved; }

    /**
     * Gets the device mode as a mode configuration structure.
     *
     * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
     *
     */
    void Get(ModeConfig &aModeConfig) const;

    /**
     * this method sets the device mode from a given mode configuration structure.
     *
     * @param[in] aModeConfig   A mode configuration structure.
     *
     */
    void Set(const ModeConfig &aModeConfig);

    /**
     * Indicates whether or not the device is rx-on-when-idle.
     *
     * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
     * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
     *
     */
    bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }

    /**
     * Indicates whether or not the device is a Full Thread Device.
     *
     * @retval TRUE   If the device is Full Thread Device.
     * @retval FALSE  If the device if not Full Thread Device.
     *
     */
    bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }

    /**
     * Gets the Network Data type (full set or stable subset) that the device requests.
     *
     * @returns The Network Data type requested by this device.
     *
     */
    NetworkData::Type GetNetworkDataType(void) const
    {
        return (mMode & kModeFullNetworkData) ? NetworkData::kFullSet : NetworkData::kStableSubset;
    }

    /**
     * Indicates whether or not the device is a Minimal End Device.
     *
     * @retval TRUE   If the device is a Minimal End Device.
     * @retval FALSE  If the device is not a Minimal End Device.
     *
     */
    bool IsMinimalEndDevice(void) const
    {
        return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
    }

    /**
     * Indicates whether or not the device mode flags are valid.
     *
     * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
     *
     * @returns TRUE if , FALSE otherwise.
     * @retval TRUE   If the device mode flags are valid.
     * @retval FALSE  If the device mode flags are not valid.
     *
     */
    bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }

    /**
     * Converts the device mode into a human-readable string.
     *
     * @returns An `InfoString` object representing the device mode.
     *
     */
    InfoString ToString(void) const;

private:
    uint8_t mMode;
};

#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
/**
 * Represents device properties.
 *
 * The device properties are used for calculating the local leader weight on the device.
 *
 */
class DeviceProperties : public otDeviceProperties, public Clearable<DeviceProperties>
{
public:
    /**
     * Represents the device's power supply property.
     *
     */
    enum PowerSupply : uint8_t
    {
        kPowerSupplyBattery          = OT_POWER_SUPPLY_BATTERY,           ///< Battery powered.
        kPowerSupplyExternal         = OT_POWER_SUPPLY_EXTERNAL,          ///< External powered.
        kPowerSupplyExternalStable   = OT_POWER_SUPPLY_EXTERNAL_STABLE,   ///< Stable external power with backup.
        kPowerSupplyExternalUnstable = OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, ///< Unstable external power.
    };

    /**
     * Initializes `DeviceProperties` with default values.
     *
     */
    DeviceProperties(void);

    /**
     * Clamps the `mLeaderWeightAdjustment` value to the valid range.
     *
     */
    void ClampWeightAdjustment(void);

    /**
     * Calculates the leader weight based on the device properties.
     *
     * @returns The calculated leader weight.
     *
     */
    uint8_t CalculateLeaderWeight(void) const;

private:
    static constexpr int8_t  kDefaultAdjustment        = OPENTHREAD_CONFIG_MLE_DEFAULT_LEADER_WEIGHT_ADJUSTMENT;
    static constexpr uint8_t kBaseWeight               = 64;
    static constexpr int8_t  kBorderRouterInc          = +1;
    static constexpr int8_t  kCcmBorderRouterInc       = +8;
    static constexpr int8_t  kIsUnstableInc            = -4;
    static constexpr int8_t  kPowerBatteryInc          = -8;
    static constexpr int8_t  kPowerExternalInc         = 0;
    static constexpr int8_t  kPowerExternalStableInc   = +4;
    static constexpr int8_t  kPowerExternalUnstableInc = -4;
    static constexpr int8_t  kMinAdjustment            = -16;
    static constexpr int8_t  kMaxAdjustment            = +16;

    static_assert(kDefaultAdjustment >= kMinAdjustment, "Invalid default weight adjustment");
    static_assert(kDefaultAdjustment <= kMaxAdjustment, "Invalid default weight adjustment");
};

#endif // #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE

/**
 * Represents the Thread Leader Data.
 *
 */
class LeaderData : public otLeaderData, public Clearable<LeaderData>
{
public:
    /**
     * Returns the Partition ID value.
     *
     * @returns The Partition ID value.
     *
     */
    uint32_t GetPartitionId(void) const { return mPartitionId; }

    /**
     * Sets the Partition ID value.
     *
     * @param[in]  aPartitionId  The Partition ID value.
     *
     */
    void SetPartitionId(uint32_t aPartitionId) { mPartitionId = aPartitionId; }

    /**
     * Returns the Weighting value.
     *
     * @returns The Weighting value.
     *
     */
    uint8_t GetWeighting(void) const { return mWeighting; }

    /**
     * Sets the Weighting value.
     *
     * @param[in]  aWeighting  The Weighting value.
     *
     */
    void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }

    /**
     * Returns the Data Version value for a type (full set or stable subset).
     *
     * @param[in] aType   The Network Data type (full set or stable subset).
     *
     * @returns The Data Version value for @p aType.
     *
     */
    uint8_t GetDataVersion(NetworkData::Type aType) const
    {
        return (aType == NetworkData::kFullSet) ? mDataVersion : mStableDataVersion;
    }

    /**
     * Sets the Data Version value.
     *
     * @param[in]  aVersion  The Data Version value.
     *
     */
    void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }

    /**
     * Sets the Stable Data Version value.
     *
     * @param[in]  aVersion  The Stable Data Version value.
     *
     */
    void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }

    /**
     * Returns the Leader Router ID value.
     *
     * @returns The Leader Router ID value.
     *
     */
    uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }

    /**
     * Sets the Leader Router ID value.
     *
     * @param[in]  aRouterId  The Leader Router ID value.
     *
     */
    void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
};

OT_TOOL_PACKED_BEGIN
class RouterIdSet : public Equatable<RouterIdSet>
{
public:
    /**
     * Clears the Router Id Set.
     *
     */
    void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }

    /**
     * Indicates whether or not a Router ID bit is set.
     *
     * @param[in]  aRouterId  The Router ID.
     *
     * @retval TRUE   If the Router ID bit is set.
     * @retval FALSE  If the Router ID bit is not set.
     *
     */
    bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & MaskFor(aRouterId)) != 0; }

    /**
     * Sets a given Router ID.
     *
     * @param[in]  aRouterId  The Router ID to set.
     *
     */
    void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= MaskFor(aRouterId); }

    /**
     * Removes a given Router ID.
     *
     * @param[in]  aRouterId  The Router ID to remove.
     *
     */
    void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~MaskFor(aRouterId); }

    /**
     * Calculates the number of allocated Router IDs in the set.
     *
     * @returns The number of allocated Router IDs in the set.
     *
     */
    uint8_t GetNumberOfAllocatedIds(void) const;

private:
    static uint8_t MaskFor(uint8_t aRouterId) { return (0x80 >> (aRouterId % 8)); }

    uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
} OT_TOOL_PACKED_END;

class TxChallenge;

/**
 * Represents a received Challenge data from an MLE message.
 *
 */
class RxChallenge
{
public:
    static constexpr uint8_t kMinSize = 4; ///< Minimum Challenge size in bytes.
    static constexpr uint8_t kMaxSize = 8; ///< Maximum Challenge size in bytes.

    /**
     * Clears the challenge.
     *
     */
    void Clear(void) { mArray.Clear(); }

    /**
     * Indicates whether or not the challenge data is empty.
     *
     * @retval TRUE  The challenge is empty.
     * @retval FALSE The challenge is not empty.
     *
     */
    bool IsEmpty(void) const { return mArray.GetLength() == 0; }

    /**
     * Gets a pointer to challenge data bytes.
     *
     * @return A pointer to the challenge data bytes.
     *
     */
    const uint8_t *GetBytes(void) const { return mArray.GetArrayBuffer(); }

    /**
     * Gets the length of challenge data.
     *
     * @returns The length of challenge data in bytes.
     *
     */
    uint8_t GetLength(void) const { return mArray.GetLength(); }

    /**
     * Reads the challenge bytes from given message.
     *
     * If the given @p aLength is longer than `kMaxSize`, only `kMaxSize` bytes will be read.
     *
     * @param[in] aMessage   The message to read the challenge from.
     * @param[in] aOffset    The offset in @p aMessage to read from.
     * @param[in] aLength    Number of bytes to read.
     *
     * @retval kErrorNone     Successfully read the challenge data from @p aMessage.
     * @retval kErrorParse    Not enough bytes to read, or invalid @p aLength (smaller than `kMinSize`).
     *
     */
    Error ReadFrom(const Message &aMessage, uint16_t aOffset, uint16_t aLength);

    /**
     * Compares the `RxChallenge` with a given `TxChallenge`.
     *
     * @param[in] aTxChallenge  The `TxChallenge` to compare with.
     *
     * @retval TRUE  The two challenges are equal.
     * @retval FALSE The two challenges are not equal.
     *
     */
    bool operator==(const TxChallenge &aTxChallenge) const;

private:
    Array<uint8_t, kMaxSize> mArray;
};

/**
 * Represents a max-sized challenge data to send in MLE message.
 *
 * OpenThread always uses max size challenge when sending MLE messages.
 *
 */
class TxChallenge : public Clearable<TxChallenge>
{
    friend class RxChallenge;

public:
    /**
     * Generates a cryptographically secure random sequence to populate the challenge data.
     *
     */
    void GenerateRandom(void);

private:
    uint8_t m8[RxChallenge::kMaxSize];
};

/**
 * Represents a MLE Key Material
 *
 */
typedef Mac::KeyMaterial KeyMaterial;

/**
 * Represents a MLE Key.
 *
 */
typedef Mac::Key Key;

/**
 * Represents the Thread MLE counters.
 *
 */
typedef otMleCounters Counters;

/**
 * Derives the Child ID from a given RLOC16.
 *
 * @param[in]  aRloc16  The RLOC16 value.
 *
 * @returns The Child ID portion of an RLOC16.
 *
 */
inline uint16_t ChildIdFromRloc16(uint16_t aRloc16) { return aRloc16 & kMaxChildId; }

/**
 * Derives the Router ID portion from a given RLOC16.
 *
 * @param[in]  aRloc16  The RLOC16 value.
 *
 * @returns The Router ID portion of an RLOC16.
 *
 */
inline uint8_t RouterIdFromRloc16(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }

/**
 * Returns whether the two RLOC16 have the same Router ID.
 *
 * @param[in]  aRloc16A  The first RLOC16 value.
 * @param[in]  aRloc16B  The second RLOC16 value.
 *
 * @returns true if the two RLOC16 have the same Router ID, false otherwise.
 *
 */
inline bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
{
    return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B);
}

/**
 * Returns the Service ID corresponding to a Service ALOC16.
 *
 * @param[in]  aAloc16  The Service ALOC16 value.
 *
 * @returns The Service ID corresponding to given ALOC16.
 *
 */
inline uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast<uint8_t>(aAloc16 - kAloc16ServiceStart); }

/**
 * Returns the Service ALOC16 corresponding to a Service ID.
 *
 * @param[in]  aServiceId  The Service ID value.
 *
 * @returns The Service ALOC16 corresponding to given ID.
 *
 */
inline uint16_t ServiceAlocFromId(uint8_t aServiceId)
{
    return static_cast<uint16_t>(aServiceId + kAloc16ServiceStart);
}

/**
 * Returns the Commissioner Aloc corresponding to a Commissioner Session ID.
 *
 * @param[in]  aSessionId   The Commissioner Session ID value.
 *
 * @returns The Commissioner ALOC16 corresponding to given ID.
 *
 */
inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId)
{
    return static_cast<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
}

/**
 * Derives RLOC16 from a given Router ID.
 *
 * @param[in]  aRouterId  The Router ID value.
 *
 * @returns The RLOC16 corresponding to the given Router ID.
 *
 */
inline uint16_t Rloc16FromRouterId(uint8_t aRouterId) { return static_cast<uint16_t>(aRouterId << kRouterIdOffset); }

/**
 * Indicates whether or not @p aRloc16 refers to an active router.
 *
 * @param[in]  aRloc16  The RLOC16 value.
 *
 * @retval TRUE   If @p aRloc16 refers to an active router.
 * @retval FALSE  If @p aRloc16 does not refer to an active router.
 *
 */
inline bool IsActiveRouter(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }

/**
 * Converts a device role into a human-readable string.
 *
 * @param[in] aRole  The device role to convert.
 *
 * @returns The string representation of @p aRole.
 *
 */
const char *RoleToString(DeviceRole aRole);

/**
 * @}
 *
 */

} // namespace Mle

DefineCoreType(otLeaderData, Mle::LeaderData);
DefineMapEnum(otDeviceRole, Mle::DeviceRole);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
DefineCoreType(otDeviceProperties, Mle::DeviceProperties);
DefineMapEnum(otPowerSupply, Mle::DeviceProperties::PowerSupply);
#endif

} // namespace ot

#endif // MLE_TYPES_HPP_
