/*
 *  Copyright (c) 2020, 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 generating and processing Link Metrics TLVs.
 *
 */

#ifndef LINK_METRICS_TLVS_HPP_
#define LINK_METRICS_TLVS_HPP_

#include "openthread-core-config.h"

#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE

#include <openthread/link_metrics.h>

#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/message.hpp"
#include "common/tlvs.hpp"

namespace ot {
namespace LinkMetrics {

/**
 * This type represents Link Metric Flags indicating a set of metrics.
 *
 * @sa otLinkMetrics
 *
 */
class Metrics : public otLinkMetrics, public Clearable<Metrics>
{
};

/**
 * This class defines constants related to Link Metrics Sub-TLVs.
 *
 */
class SubTlv
{
public:
    /**
     * Link Metrics Sub-TLV types.
     *
     */
    enum Type : uint8_t
    {
        kReport        = 0, ///< Report Sub-TLV
        kQueryId       = 1, ///< Query ID Sub-TLV
        kQueryOptions  = 2, ///< Query Options Sub-TLV
        kFwdProbingReg = 3, ///< Forward Probing Registration Sub-TLV
        kStatus        = 5, ///< Status Sub-TLV
        kEnhAckConfig  = 7, ///< Enhanced ACK Configuration Sub-TLV
    };
};

/**
 * This class defines Link Metrics Query ID Sub-TLV constants and types.
 *
 */
typedef UintTlvInfo<SubTlv::kQueryId, uint8_t> QueryIdSubTlv;

/**
 * This class implements Link Metrics Type ID Flags generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN class TypeIdFlags
{
    static constexpr uint8_t kExtendedFlag     = 1 << 7;
    static constexpr uint8_t kLengthOffset     = 6;
    static constexpr uint8_t kLengthFlag       = 1 << kLengthOffset;
    static constexpr uint8_t kTypeEnumOffset   = 3;
    static constexpr uint8_t kTypeEnumMask     = 7 << kTypeEnumOffset;
    static constexpr uint8_t kMetricEnumOffset = 0;
    static constexpr uint8_t kMetricEnumMask   = 7 << kMetricEnumOffset;

public:
    /**
     * This enumeration specifies the Length field in Type ID Flags.
     *
     */
    enum Length
    {
        kShortLength    = 0, ///< Short value length (1 byte value)
        kExtendedLength = 1, ///< Extended value length (4 bytes value)
    };

    /**
     * This enumeration specifies the Type values in Type ID Flags.
     *
     */
    enum TypeEnum : uint8_t
    {
        kTypeCountSummation   = 0, ///< Count or summation
        kTypeExpMovingAverage = 1, ///< Exponential moving average.
        kTypeReserved         = 2, ///< Reserved for future use.
    };

    /**
     * This enumeration specifies the Metric values in Type ID Flag.
     *
     */
    enum MetricEnum : uint8_t
    {
        kMetricPdusReceived = 0, ///< Number of PDUs received.
        kMetricLqi          = 1, ///< Link Quality Indicator.
        kMetricLinkMargin   = 2, ///< Link Margin.
        kMetricRssi         = 3, ///< RSSI in dbm.
    };

    /**
     * This constant defines the raw value for Type ID Flag for PDU.
     *
     */
    static constexpr uint8_t kPdu = (kExtendedLength << kLengthOffset) | (kTypeCountSummation << kTypeEnumOffset) |
                                    (kMetricPdusReceived << kMetricEnumOffset);

    /**
     * This constant defines the raw value for Type ID Flag for LQI.
     *
     */
    static constexpr uint8_t kLqi = (kShortLength << kLengthOffset) | (kTypeExpMovingAverage << kTypeEnumOffset) |
                                    (kMetricLqi << kMetricEnumOffset);

    /**
     * This constant defines the raw value for Type ID Flag for Link Margin.
     *
     */
    static constexpr uint8_t kLinkMargin = (kShortLength << kLengthOffset) |
                                           (kTypeExpMovingAverage << kTypeEnumOffset) |
                                           (kMetricLinkMargin << kMetricEnumOffset);

    /**
     * This constant defines the raw value for Type ID Flag for RSSI
     *
     */
    static constexpr uint8_t kRssi = (kShortLength << kLengthOffset) | (kTypeExpMovingAverage << kTypeEnumOffset) |
                                     (kMetricRssi << kMetricEnumOffset);

    /**
     * Default constructor.
     *
     */
    TypeIdFlags(void) = default;

    /**
     * Constructor to initialize from raw value.
     *
     * @param[in] aFlags  The raw flags value.
     *
     */
    explicit TypeIdFlags(uint8_t aFlags)
        : mFlags(aFlags)
    {
    }

    /**
     * This method initializes the Type ID value
     *
     */
    void Init(void) { mFlags = 0; }

    /**
     * This method clears the Extended flag.
     *
     */
    void ClearExtendedFlag(void) { mFlags &= ~kExtendedFlag; }

    /**
     * This method sets the Extended flag, indicating an additional second flags byte after the current 1-byte flags.
     * MUST NOT set in Thread 1.2.1.
     *
     */
    void SetExtendedFlag(void) { mFlags |= kExtendedFlag; }

    /**
     * This method indicates whether or not the Extended flag is set.
     *
     * @retval true   The Extended flag is set.
     * @retval false  The Extended flag is not set.
     *
     */
    bool IsExtendedFlagSet(void) const { return (mFlags & kExtendedFlag) != 0; }

    /**
     * This method clears value length flag.
     *
     */
    void ClearLengthFlag(void) { mFlags &= ~kLengthFlag; }

    /**
     * This method sets the value length flag.
     *
     */
    void SetLengthFlag(void) { mFlags |= kLengthFlag; }

    /**
     * This method indicates whether or not the value length flag is set.
     *
     * @retval true   The value length flag is set, extended value length (4 bytes)
     * @retval false  The value length flag is not set, short value length (1 byte)
     *
     */
    bool IsLengthFlagSet(void) const { return (mFlags & kLengthFlag) != 0; }

    /**
     * This method sets the Type/Average Enum.
     *
     * @param[in]  aTypeEnum  Type/Average Enum.
     *
     */
    void SetTypeEnum(TypeEnum aTypeEnum)
    {
        mFlags = (mFlags & ~kTypeEnumMask) | ((aTypeEnum << kTypeEnumOffset) & kTypeEnumMask);
    }

    /**
     * This method returns the Type/Average Enum.
     *
     * @returns The Type/Average Enum.
     *
     */
    TypeEnum GetTypeEnum(void) const { return static_cast<TypeEnum>((mFlags & kTypeEnumMask) >> kTypeEnumOffset); }

    /**
     * This method sets the Metric Enum.
     *
     * @param[in]  aMetricEnum  Metric Enum.
     *
     */
    void SetMetricEnum(MetricEnum aMetricEnum)
    {
        mFlags = (mFlags & ~kMetricEnumMask) | ((aMetricEnum << kMetricEnumOffset) & kMetricEnumMask);
    }

    /**
     * This method returns the Metric Enum.
     *
     * @returns The Metric Enum.
     *
     */
    MetricEnum GetMetricEnum(void) const
    {
        return static_cast<MetricEnum>((mFlags & kMetricEnumMask) >> kMetricEnumOffset);
    }

    /**
     * This method returns the raw value of the entire TypeIdFlags.
     *
     * @returns The raw value of TypeIdFlags.
     *
     */
    uint8_t GetRawValue(void) const { return mFlags; }

    /**
     * This method sets the raw value of the entire TypeIdFlags.
     *
     * @param[in]  aFlags  The raw flags value.
     *
     */
    void SetRawValue(uint8_t aFlags) { mFlags = aFlags; }

private:
    uint8_t mFlags;
} OT_TOOL_PACKED_END;

/**
 * This class implements Link Metrics Report Sub-TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class ReportSubTlv : public Tlv, public TlvInfo<SubTlv::kReport>
{
public:
    /**
     * This method initializes the TLV.
     *
     */
    void Init(void)
    {
        SetType(SubTlv::kReport);
        SetLength(sizeof(*this) - sizeof(Tlv));
    }

    /**
     * This method indicates whether or not the TLV appears to be well-formed.
     *
     * @retval true   The TLV appears to be well-formed.
     * @retval false  The TLV does not appear to be well-formed.
     *
     */
    bool IsValid(void) const { return GetLength() >= sizeof(TypeIdFlags) + sizeof(uint8_t); }

    /**
     * This method returns the Link Metrics Type ID.
     *
     * @returns The Link Metrics Type ID.
     *
     */
    TypeIdFlags GetMetricsTypeId(void) const { return mMetricsTypeId; }

    /**
     * This method sets the Link Metrics Type ID.
     *
     * @param[in]  aMetricsTypeId  The Link Metrics Type ID to set.
     *
     */
    void SetMetricsTypeId(TypeIdFlags aMetricsTypeId)
    {
        mMetricsTypeId = aMetricsTypeId;

        if (!aMetricsTypeId.IsLengthFlagSet())
        {
            SetLength(sizeof(*this) - sizeof(Tlv) - sizeof(uint32_t) + sizeof(uint8_t)); // The value is 1 byte long
        }
    }

    /**
     * This method returns the metric value in 8 bits.
     *
     * @returns The metric value.
     *
     */
    uint8_t GetMetricsValue8(void) const { return mMetricsValue.m8; }

    /**
     * This method returns the metric value in 32 bits.
     *
     * @returns The metric value.
     *
     */
    uint32_t GetMetricsValue32(void) const { return mMetricsValue.m32; }

    /**
     * This method sets the metric value (8 bits).
     *
     * @param[in]  aMetricsValue  Metrics value.
     *
     */
    void SetMetricsValue8(uint8_t aMetricsValue) { mMetricsValue.m8 = aMetricsValue; }

    /**
     * This method sets the metric value (32 bits).
     *
     * @param[in]  aMetricsValue  Metrics value.
     *
     */
    void SetMetricsValue32(uint32_t aMetricsValue) { mMetricsValue.m32 = aMetricsValue; }

private:
    TypeIdFlags mMetricsTypeId;
    union
    {
        uint8_t  m8;
        uint32_t m32;
    } mMetricsValue;
} OT_TOOL_PACKED_END;

/**
 * This class implements Link Metrics Query Options Sub-TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class QueryOptionsSubTlv : public Tlv, public TlvInfo<SubTlv::kQueryOptions>
{
public:
    /**
     * This method initializes the TLV.
     *
     */
    void Init(void)
    {
        SetType(SubTlv::kQueryOptions);
        SetLength(0);
    }

    /**
     * This method indicates whether or not the TLV appears to be well-formed.
     *
     * @retval TRUE   If the TLV appears to be well-formed.
     * @retval FALSE  If the TLV does not appear to be well-formed.
     *
     */
    bool IsValid(void) const { return GetLength() >= sizeof(TypeIdFlags); }

} OT_TOOL_PACKED_END;

/**
 * This class implements Series Flags for Forward Tracking Series.
 *
 */
OT_TOOL_PACKED_BEGIN
class SeriesFlags
{
public:
    /**
     * This type represents which frames to be accounted in a Forward Tracking Series.
     *
     * @sa otLinkMetricsSeriesFlags
     *
     */
    typedef otLinkMetricsSeriesFlags Info;

    /**
     * Default constructor.
     *
     */
    SeriesFlags(void)
        : mFlags(0)
    {
    }

    /**
     * This method sets the values from an `Info` object.
     *
     * @param[in]  aSeriesFlags  The `Info` object.
     *
     */
    void SetFrom(const Info &aSeriesFlags)
    {
        Clear();

        if (aSeriesFlags.mLinkProbe)
        {
            SetLinkProbeFlag();
        }

        if (aSeriesFlags.mMacData)
        {
            SetMacDataFlag();
        }

        if (aSeriesFlags.mMacDataRequest)
        {
            SetMacDataRequestFlag();
        }

        if (aSeriesFlags.mMacAck)
        {
            SetMacAckFlag();
        }
    }

    /**
     * This method clears the Link Probe flag.
     *
     */
    void ClearLinkProbeFlag(void) { mFlags &= ~kLinkProbeFlag; }

    /**
     * This method sets the Link Probe flag.
     *
     */
    void SetLinkProbeFlag(void) { mFlags |= kLinkProbeFlag; }

    /**
     * This method indicates whether or not the Link Probe flag is set.
     *
     * @retval true   The Link Probe flag is set.
     * @retval false  The Link Probe flag is not set.
     *
     */
    bool IsLinkProbeFlagSet(void) const { return (mFlags & kLinkProbeFlag) != 0; }

    /**
     * This method clears the MAC Data flag.
     *
     */
    void ClearMacDataFlag(void) { mFlags &= ~kMacDataFlag; }

    /**
     * This method sets the MAC Data flag.
     *
     */
    void SetMacDataFlag(void) { mFlags |= kMacDataFlag; }

    /**
     * This method indicates whether or not the MAC Data flag is set.
     *
     * @retval true   The MAC Data flag is set.
     * @retval false  The MAC Data flag is not set.
     *
     */
    bool IsMacDataFlagSet(void) const { return (mFlags & kMacDataFlag) != 0; }

    /**
     * This method clears the MAC Data Request flag.
     *
     */
    void ClearMacDataRequestFlag(void) { mFlags &= ~kMacDataRequestFlag; }

    /**
     * This method sets the MAC Data Request flag.
     *
     */
    void SetMacDataRequestFlag(void) { mFlags |= kMacDataRequestFlag; }

    /**
     * This method indicates whether or not the MAC Data Request flag is set.
     *
     * @retval true   The MAC Data Request flag is set.
     * @retval false  The MAC Data Request flag is not set.
     *
     */
    bool IsMacDataRequestFlagSet(void) const { return (mFlags & kMacDataRequestFlag) != 0; }

    /**
     * This method clears the Mac Ack flag.
     *
     */
    void ClearMacAckFlag(void) { mFlags &= ~kMacAckFlag; }

    /**
     * This method sets the Mac Ack flag.
     *
     */
    void SetMacAckFlag(void) { mFlags |= kMacAckFlag; }

    /**
     * This method indicates whether or not the Mac Ack flag is set.
     *
     * @retval true   The Mac Ack flag is set.
     * @retval false  The Mac Ack flag is not set.
     *
     */
    bool IsMacAckFlagSet(void) const { return (mFlags & kMacAckFlag) != 0; }

    /**
     * This method returns the raw value of flags.
     *
     */
    uint8_t GetRawValue(void) const { return mFlags; }

    /**
     * This method clears the all the flags.
     *
     */
    void Clear(void) { mFlags = 0; }

private:
    static constexpr uint8_t kLinkProbeFlag      = 1 << 0;
    static constexpr uint8_t kMacDataFlag        = 1 << 1;
    static constexpr uint8_t kMacDataRequestFlag = 1 << 2;
    static constexpr uint8_t kMacAckFlag         = 1 << 3;

    uint8_t mFlags;
} OT_TOOL_PACKED_END;

/**
 * This enumeration type represent Enhanced-ACK Flags.
 *
 */
enum EnhAckFlags : uint8_t
{
    kEnhAckClear    = OT_LINK_METRICS_ENH_ACK_CLEAR,    ///< Clear.
    kEnhAckRegister = OT_LINK_METRICS_ENH_ACK_REGISTER, ///< Register.
};

static uint8_t TypeIdFlagsFromMetrics(TypeIdFlags aTypeIdFlags[], const Metrics &aMetrics)
{
    uint8_t count = 0;

    if (aMetrics.mPduCount)
    {
        aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kPdu);
    }

    if (aMetrics.mLqi)
    {
        aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLqi);
    }

    if (aMetrics.mLinkMargin)
    {
        aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLinkMargin);
    }

    if (aMetrics.mRssi)
    {
        aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kRssi);
    }

#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
    if (aMetrics.mReserved)
    {
        for (uint8_t i = 0; i < count; i++)
        {
            aTypeIdFlags[i].SetTypeEnum(TypeIdFlags::kTypeReserved);
        }
    }
#endif

    return count;
}

OT_TOOL_PACKED_BEGIN
class EnhAckConfigSubTlv : public Tlv, public TlvInfo<SubTlv::kEnhAckConfig>
{
public:
    /**
     * Default constructor
     *
     */
    EnhAckConfigSubTlv(void) { Init(); }

    /**
     * This method initializes the TLV.
     *
     */
    void Init(void)
    {
        SetType(SubTlv::kEnhAckConfig);
        SetLength(sizeof(EnhAckFlags));
    }

    /**
     * This method sets Enhanced ACK Flags.
     *
     * @param[in] aEnhAckFlags  The value of Enhanced ACK Flags.
     *
     */
    void SetEnhAckFlags(EnhAckFlags aEnhAckFlags)
    {
        memcpy(mSubTlvs + kEnhAckFlagsOffset, &aEnhAckFlags, sizeof(aEnhAckFlags));
    }

    /**
     * This method sets Type ID Flags.
     *
     * @param[in] aMetrics  A metrics flags to indicate the Type ID Flags.
     *
     */
    void SetTypeIdFlags(const Metrics &aMetrics)
    {
        uint8_t count;

        count = TypeIdFlagsFromMetrics(reinterpret_cast<TypeIdFlags *>(mSubTlvs + kTypeIdFlagsOffset), aMetrics);

        OT_ASSERT(count <= kMaxTypeIdFlagsEnhAck);

        SetLength(sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * count);
    }

private:
    static constexpr uint8_t  kMaxTypeIdFlagsEnhAck = 3;
    static constexpr uint8_t  kEnhAckFlagsOffset    = 0;
    static constexpr uint16_t kTypeIdFlagsOffset    = sizeof(TypeIdFlags);

    uint8_t mSubTlvs[sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * kMaxTypeIdFlagsEnhAck];
} OT_TOOL_PACKED_END;

} // namespace LinkMetrics
} // namespace ot

#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE

#endif // LINK_METRICS_TLVS_HPP_
