/*
 *
 *    Copyright (c) 2021 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <lib/core/CHIPCore.h>
#include <lib/support/Span.h>

namespace chip {
namespace Thread {

class ThreadTLV;

constexpr size_t kChannel_NotSpecified = UINT8_MAX;
constexpr size_t kPANId_NotSpecified   = UINT16_MAX;

constexpr size_t kSizeOperationalDataset = 254;

constexpr size_t kSizeNetworkName     = 16;
constexpr size_t kSizeExtendedPanId   = 8;
constexpr size_t kSizeMasterKey       = 16;
constexpr size_t kSizeMeshLocalPrefix = 8;
constexpr size_t kSizePSKc            = 16;

/**
 * This class provides methods to manipulate Thread operational dataset.
 *
 */
class OperationalDataset
{
public:
    /**
     * This method initializes the dataset with the given dataset.
     *
     * @param[in]   aData       Thread Operational dataset in octects.
     *
     * @retval CHIP_NO_ERROR                Successfully initialized the dataset.
     * @retval CHIP_ERROR_INVALID_ARGUMENT  The dataset length @p aLength is too long or @p data is corrupted.
     *
     */
    CHIP_ERROR Init(ByteSpan aData);

    /**
     * This method retrieves Thread active timestamp from the dataset.
     *
     * @param[out]  aActiveTimestamp    A reference to receive the active timestamp.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the active timestamp.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread active timestamp is not present in the dataset.
     *
     */
    CHIP_ERROR GetActiveTimestamp(uint64_t & aActiveTimestamp) const;

    /**
     * This method sets Thread active timestamp to the dataset.
     *
     * @param[in]   aActiveTimestamp    The Thread active timestamp.
     *
     * @retval CHIP_NO_ERROR           Successfully set the active timestamp.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread active timestamp.
     *
     */
    CHIP_ERROR SetActiveTimestamp(uint64_t aActiveTimestamp);

    /**
     * This method retrieves Thread channel from the dataset.
     *
     * @param[out]  aChannel    A reference to receive the channel.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the channel.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread channel is not present in the dataset.
     *
     */
    CHIP_ERROR GetChannel(uint16_t & aChannel) const;

    /**
     * This method sets Thread channel to the dataset.
     *
     * @param[in]   aChannel    The Thread channel.
     *
     * @retval CHIP_NO_ERROR           Successfully set the channel.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread channel.
     *
     */
    CHIP_ERROR SetChannel(uint16_t aChannel);

    /**
     * This method retrieves Thread extended PAN ID from the dataset.
     *
     * @param[out]  aExtendedPanId  A reference to receive the extended PAN ID.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the extended PAN ID.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread extended PAN ID is not present in the dataset.
     *
     */
    CHIP_ERROR GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const;

    /**
     * This method returns a const ByteSpan to the extended PAN ID in the dataset.
     * This can be used to pass the extended PAN ID to a cluster command without the use of external memory.
     *
     * @param[out]  span  A reference to receive the location of the extended PAN ID.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the extended PAN ID.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread extended PAN ID is not present in the dataset.
     *
     */
    CHIP_ERROR GetExtendedPanIdAsByteSpan(ByteSpan & span) const;

    /**
     * This method sets Thread extended PAN ID to the dataset.
     *
     * @param[in]   aExtendedPanId  The Thread extended PAN ID.
     *
     * @retval CHIP_NO_ERROR           Successfully set the extended PAN ID.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread extended PAN ID.
     *
     */
    CHIP_ERROR SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]);

    /**
     * This method retrieves Thread master key from the dataset.
     *
     * @param[out]  aMasterKey  A reference to receive the master key.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the master key.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread master key is not present in the dataset.
     *
     */
    CHIP_ERROR GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const;

    /**
     * This method sets Thread master key to the dataset.
     *
     * @param[in]   aMasterKey         The Thread master key.
     *
     * @retval CHIP_NO_ERROR           Successfully set the master key.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread master key.
     *
     */
    CHIP_ERROR SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]);

    /**
     * This method unsets Thread master key to the dataset.
     *
     */
    void UnsetMasterKey(void);

    /**
     * This method retrieves Thread mesh local prefix from the dataset.
     *
     * @param[out]  aMeshLocalPrefix    A reference to receive the mesh local prefix.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the mesh local prefix.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread mesh local prefix is not present in the dataset.
     *
     */
    CHIP_ERROR GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const;

    /**
     * This method sets Thread mesh local prefix to the dataset.
     *
     * @param[in]   aMeshLocalPrefix   The Thread mesh local prefix.
     *
     * @retval CHIP_NO_ERROR           Successfully set the Thread mesh local prefix.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread mesh local prefix.
     *
     */
    CHIP_ERROR SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]);

    /**
     * This method retrieves Thread network name from the dataset.
     *
     * @param[out]  aNetworkName    A reference to receive the Thread network name.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the network name.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread network name is not present in the dataset.
     *
     */
    CHIP_ERROR GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const;

    /**
     * This method sets Thread network name to the dataset.
     *
     * @param[in]   aNetworkName    The Thread network name.
     *
     * @retval CHIP_NO_ERROR           Successfully set the network name.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread network name.
     *
     */
    CHIP_ERROR SetNetworkName(const char * aNetworkName);

    /**
     * This method retrieves Thread PAN ID from the dataset.
     *
     * @param[out]  aPanId  A reference to receive the PAN ID.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the PAN ID.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread PAN ID is not present in the dataset.
     *
     */
    CHIP_ERROR GetPanId(uint16_t & aPanId) const;

    /**
     * This method sets Thread PAN ID to the dataset.
     *
     * @param[in]   aPanId  The Thread PAN ID.
     *
     * @retval CHIP_NO_ERROR           Successfully set the PAN ID.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread PAN ID.
     *
     */
    CHIP_ERROR SetPanId(uint16_t aPanId);

    /**
     * This method retrieves Thread PSKc from the dataset.
     *
     * @param[out]  aPSKc   A reference to receive the PSKc.
     *
     * @retval CHIP_NO_ERROR                    Successfully retrieved the PSKc.
     * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread PSKc is not present in the dataset.
     *
     */
    CHIP_ERROR GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const;

    /**
     * This method sets Thread PSKc to the dataset.
     *
     * @param[in]   aPSKc   The Thread PSKc.
     *
     * @retval CHIP_NO_ERROR           Successfully set the PSKc.
     * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread PSKc.
     *
     */
    CHIP_ERROR SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]);

    /**
     * This method unsets Thread PSKc to the dataset.
     *
     */
    void UnsetPSKc(void);

    /**
     * This method clears all data stored in the dataset.
     */
    void Clear(void) { mLength = 0; }

    /**
     * This method checks if the dataset is ready for creating Thread network.
     *
     */
    bool IsCommissioned(void) const;

    /**
     * This method checks if the dataset is empty.
     */
    bool IsEmpty() const { return mLength == 0; }

    /**
     * This method checks whether @p aData is formatted as ThreadTLVs.
     *
     * @note This method doesn't verify ThreadTLV values are valid.
     *
     */
    static bool IsValid(ByteSpan aData);

    ByteSpan AsByteSpan(void) const { return ByteSpan(mData, mLength); }

private:
    ThreadTLV * Locate(uint8_t aType)
    {
        return const_cast<ThreadTLV *>(const_cast<const OperationalDataset *>(this)->Locate(aType));
    }
    const ThreadTLV * Locate(uint8_t aType) const;
    const ThreadTLV & Begin(void) const { return *reinterpret_cast<const ThreadTLV *>(&mData[0]); };
    ThreadTLV & Begin(void) { return const_cast<ThreadTLV &>(const_cast<const OperationalDataset *>(this)->Begin()); }
    const ThreadTLV & End(void) const { return *reinterpret_cast<const ThreadTLV *>(&mData[mLength]); };
    ThreadTLV & End(void) { return const_cast<ThreadTLV &>(const_cast<const OperationalDataset *>(this)->End()); }
    void Remove(uint8_t aType);
    void Remove(ThreadTLV & aTlv);
    ThreadTLV * MakeRoom(uint8_t aType, uint8_t aSize);
    bool Has(uint8_t aType) const { return Locate(aType) != nullptr; }

    uint8_t mData[kSizeOperationalDataset];
    uint8_t mLength;
};

} // namespace Thread
}; // namespace chip
