/*
 *  Copyright (c) 2016, 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 implements the Thread Network Data managed by the Thread Leader.
 */

#include "network_data_leader.hpp"

#include "coap/coap_message.hpp"
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "common/instance.hpp"
#include "common/locator_getters.hpp"
#include "common/logging.hpp"
#include "common/message.hpp"
#include "common/random.hpp"
#include "common/timer.hpp"
#include "mac/mac_types.hpp"
#include "thread/lowpan.hpp"
#include "thread/mle_router.hpp"
#include "thread/thread_netif.hpp"
#include "thread/thread_tlvs.hpp"
#include "thread/uri_paths.hpp"

namespace ot {
namespace NetworkData {

RegisterLogModule("NetworkData");

void LeaderBase::Reset(void)
{
    mVersion       = Random::NonCrypto::GetUint8();
    mStableVersion = Random::NonCrypto::GetUint8();
    SetLength(0);
    SignalNetDataChanged();
}

Error LeaderBase::GetServiceId(uint32_t           aEnterpriseNumber,
                               const ServiceData &aServiceData,
                               bool               aServerStable,
                               uint8_t           &aServiceId) const
{
    Error         error    = kErrorNotFound;
    Iterator      iterator = kIteratorInit;
    ServiceConfig serviceConfig;
    ServiceData   serviceData;

    while (GetNextService(iterator, serviceConfig) == kErrorNone)
    {
        serviceConfig.GetServiceData(serviceData);

        if (aEnterpriseNumber == serviceConfig.mEnterpriseNumber && aServiceData == serviceData &&
            aServerStable == serviceConfig.mServerConfig.mStable)
        {
            aServiceId = serviceConfig.mServiceId;
            ExitNow(error = kErrorNone);
        }
    }

exit:
    return error;
}

Error LeaderBase::GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const
{
    Error               error    = kErrorNotFound;
    Iterator            iterator = kIteratorInit;
    ExternalRouteConfig config;

    while (GetNextExternalRoute(iterator, config) == kErrorNone)
    {
        if (!config.mNat64 || !config.GetPrefix().IsValidNat64())
        {
            continue;
        }

        if ((error == kErrorNotFound) || (config.mPreference > aConfig.mPreference) ||
            (config.mPreference == aConfig.mPreference && config.GetPrefix() < aConfig.GetPrefix()))
        {
            aConfig = config;
            error   = kErrorNone;
        }
    }

    return error;
}

const PrefixTlv *LeaderBase::FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const
{
    // This method iterates over Prefix TLVs which match a given IPv6
    // `aAddress`. If `aPrevTlv` is `nullptr` we start from the
    // beginning. Otherwise, we search for a match after `aPrevTlv`.
    // This method returns a pointer to the next matching Prefix TLV
    // when found, or `nullptr` if no match is found.

    const PrefixTlv *prefixTlv;
    TlvIterator      tlvIterator((aPrevTlv == nullptr) ? GetTlvsStart() : aPrevTlv->GetNext(), GetTlvsEnd());

    while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
    {
        if (aAddress.MatchesPrefix(prefixTlv->GetPrefix(), prefixTlv->GetPrefixLength()))
        {
            break;
        }
    }

    return prefixTlv;
}

Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const
{
    const PrefixTlv  *prefixTlv = nullptr;
    const ContextTlv *contextTlv;

    aContext.mPrefix.SetLength(0);

    if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
    {
        GetContextForMeshLocalPrefix(aContext);
    }

    while ((prefixTlv = FindNextMatchingPrefixTlv(aAddress, prefixTlv)) != nullptr)
    {
        contextTlv = prefixTlv->FindSubTlv<ContextTlv>();

        if (contextTlv == nullptr)
        {
            continue;
        }

        if (prefixTlv->GetPrefixLength() > aContext.mPrefix.GetLength())
        {
            prefixTlv->CopyPrefixTo(aContext.mPrefix);
            aContext.mContextId    = contextTlv->GetContextId();
            aContext.mCompressFlag = contextTlv->IsCompress();
            aContext.mIsValid      = true;
        }
    }

    return (aContext.mPrefix.GetLength() > 0) ? kErrorNone : kErrorNotFound;
}

Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const
{
    Error            error = kErrorNotFound;
    TlvIterator      tlvIterator(GetTlvsStart(), GetTlvsEnd());
    const PrefixTlv *prefixTlv;

    if (aContextId == Mle::kMeshLocalPrefixContextId)
    {
        GetContextForMeshLocalPrefix(aContext);
        ExitNow(error = kErrorNone);
    }

    while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
    {
        const ContextTlv *contextTlv = prefixTlv->FindSubTlv<ContextTlv>();

        if ((contextTlv == nullptr) || (contextTlv->GetContextId() != aContextId))
        {
            continue;
        }

        prefixTlv->CopyPrefixTo(aContext.mPrefix);
        aContext.mContextId    = contextTlv->GetContextId();
        aContext.mCompressFlag = contextTlv->IsCompress();
        aContext.mIsValid      = true;
        ExitNow(error = kErrorNone);
    }

exit:
    return error;
}

void LeaderBase::GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const
{
    aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
    aContext.mContextId    = Mle::kMeshLocalPrefixContextId;
    aContext.mCompressFlag = true;
    aContext.mIsValid      = true;
}

bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const
{
    const PrefixTlv *prefixTlv = nullptr;
    bool             isOnMesh  = false;

    VerifyOrExit(!Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress), isOnMesh = true);

    while ((prefixTlv = FindNextMatchingPrefixTlv(aAddress, prefixTlv)) != nullptr)
    {
        TlvIterator            subTlvIterator(*prefixTlv);
        const BorderRouterTlv *brTlv;

        while ((brTlv = subTlvIterator.Iterate<BorderRouterTlv>()) != nullptr)
        {
            for (const BorderRouterEntry *entry = brTlv->GetFirstEntry(); entry <= brTlv->GetLastEntry();
                 entry                          = entry->GetNext())
            {
                if (entry->IsOnMesh())
                {
                    ExitNow(isOnMesh = true);
                }
            }
        }
    }

exit:
    return isOnMesh;
}

Error LeaderBase::RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const
{
    Error            error     = kErrorNoRoute;
    const PrefixTlv *prefixTlv = nullptr;

    while ((prefixTlv = FindNextMatchingPrefixTlv(aSource, prefixTlv)) != nullptr)
    {
        if (prefixTlv->FindSubTlv<BorderRouterTlv>() == nullptr)
        {
            continue;
        }

        if (ExternalRouteLookup(prefixTlv->GetDomainId(), aDestination, aRloc16) == kErrorNone)
        {
            ExitNow(error = kErrorNone);
        }

        if (DefaultRouteLookup(*prefixTlv, aRloc16) == kErrorNone)
        {
            ExitNow(error = kErrorNone);
        }
    }

exit:
    return error;
}

template <typename EntryType>
int LeaderBase::CompareRouteEntries(const EntryType &aFirst, const EntryType &aSecond) const
{
    // `EntryType` can be `HasRouteEntry` or `BorderRouterEntry`.

    return CompareRouteEntries(aFirst.GetPreference(), aFirst.GetRloc(), aSecond.GetPreference(), aSecond.GetRloc());
}

int LeaderBase::CompareRouteEntries(int8_t   aFirstPreference,
                                    uint16_t aFirstRloc,
                                    int8_t   aSecondPreference,
                                    uint16_t aSecondRloc) const
{
    // Performs three-way comparison between two BR entries.

    int result;

    // Prefer the entry with higher preference.

    result = ThreeWayCompare(aFirstPreference, aSecondPreference);
    VerifyOrExit(result == 0);

#if OPENTHREAD_MTD
    // On MTD, prefer the BR that is this device itself. This handles
    // the uncommon case where an MTD itself may be acting as BR.

    result = ThreeWayCompare((aFirstRloc == Get<Mle::Mle>().GetRloc16()), (aSecondRloc == Get<Mle::Mle>().GetRloc16()));
#endif

#if OPENTHREAD_FTD
    // If all the same, prefer the one with lower mesh path cost.
    // Lower cost is preferred so we pass the second entry's cost as
    // the first argument in the call to `ThreeWayCompare()`, i.e.,
    // if the second entry's cost is larger, we return 1 indicating
    // that the first entry is preferred over the second one.

    result = ThreeWayCompare(Get<RouterTable>().GetPathCost(aSecondRloc), Get<RouterTable>().GetPathCost(aFirstRloc));
    VerifyOrExit(result == 0);

    // If all the same, prefer the BR acting as a router over an
    // end device.
    result = ThreeWayCompare(Mle::IsActiveRouter(aFirstRloc), Mle::IsActiveRouter(aSecondRloc));
#endif

exit:
    return result;
}

Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const
{
    Error                error           = kErrorNoRoute;
    const PrefixTlv     *prefixTlv       = nullptr;
    const HasRouteEntry *bestRouteEntry  = nullptr;
    uint8_t              bestMatchLength = 0;

    while ((prefixTlv = FindNextMatchingPrefixTlv(aDestination, prefixTlv)) != nullptr)
    {
        const HasRouteTlv *hasRoute;
        uint8_t            prefixLength = prefixTlv->GetPrefixLength();
        TlvIterator        subTlvIterator(*prefixTlv);

        if (prefixTlv->GetDomainId() != aDomainId)
        {
            continue;
        }

        if ((bestRouteEntry != nullptr) && (prefixLength <= bestMatchLength))
        {
            continue;
        }

        while ((hasRoute = subTlvIterator.Iterate<HasRouteTlv>()) != nullptr)
        {
            for (const HasRouteEntry *entry = hasRoute->GetFirstEntry(); entry <= hasRoute->GetLastEntry();
                 entry                      = entry->GetNext())
            {
                if ((bestRouteEntry == nullptr) || (prefixLength > bestMatchLength) ||
                    CompareRouteEntries(*entry, *bestRouteEntry) > 0)
                {
                    bestRouteEntry  = entry;
                    bestMatchLength = prefixLength;
                }
            }
        }
    }

    if (bestRouteEntry != nullptr)
    {
        aRloc16 = bestRouteEntry->GetRloc();
        error   = kErrorNone;
    }

    return error;
}

Error LeaderBase::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const
{
    Error                    error = kErrorNoRoute;
    TlvIterator              subTlvIterator(aPrefix);
    const BorderRouterTlv   *brTlv;
    const BorderRouterEntry *route = nullptr;

    while ((brTlv = subTlvIterator.Iterate<BorderRouterTlv>()) != nullptr)
    {
        for (const BorderRouterEntry *entry = brTlv->GetFirstEntry(); entry <= brTlv->GetLastEntry();
             entry                          = entry->GetNext())
        {
            if (!entry->IsDefaultRoute())
            {
                continue;
            }

            if (route == nullptr || CompareRouteEntries(*entry, *route) > 0)
            {
                route = entry;
            }
        }
    }

    if (route != nullptr)
    {
        aRloc16 = route->GetRloc();
        error   = kErrorNone;
    }

    return error;
}

Error LeaderBase::SetNetworkData(uint8_t        aVersion,
                                 uint8_t        aStableVersion,
                                 Type           aType,
                                 const Message &aMessage,
                                 uint16_t       aOffset,
                                 uint16_t       aLength)
{
    Error error = kErrorNone;

    VerifyOrExit(aLength <= kMaxSize, error = kErrorParse);
    SuccessOrExit(error = aMessage.Read(aOffset, GetBytes(), aLength));

    SetLength(static_cast<uint8_t>(aLength));
    mVersion       = aVersion;
    mStableVersion = aStableVersion;

    if (aType == kStableSubset)
    {
        RemoveTemporaryData();
    }

#if OPENTHREAD_FTD
    if (Get<Mle::MleRouter>().IsLeader())
    {
        Get<Leader>().HandleNetworkDataRestoredAfterReset();
    }
#endif

    DumpDebg("SetNetworkData", GetBytes(), GetLength());

    SignalNetDataChanged();

exit:
    return error;
}

Error LeaderBase::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength)
{
    Error                 error = kErrorNone;
    CommissioningDataTlv *commissioningDataTlv;

    RemoveCommissioningData();

    if (aValueLength > 0)
    {
        VerifyOrExit(aValueLength <= kMaxSize - sizeof(CommissioningDataTlv), error = kErrorNoBufs);
        commissioningDataTlv = As<CommissioningDataTlv>(AppendTlv(sizeof(CommissioningDataTlv) + aValueLength));
        VerifyOrExit(commissioningDataTlv != nullptr, error = kErrorNoBufs);

        commissioningDataTlv->Init();
        commissioningDataTlv->SetLength(aValueLength);
        memcpy(commissioningDataTlv->GetValue(), aValue, aValueLength);
    }

    mVersion++;
    SignalNetDataChanged();

exit:
    return error;
}

const CommissioningDataTlv *LeaderBase::GetCommissioningData(void) const
{
    return NetworkDataTlv::Find<CommissioningDataTlv>(GetTlvsStart(), GetTlvsEnd());
}

const MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const
{
    const MeshCoP::Tlv   *rval = nullptr;
    const NetworkDataTlv *commissioningDataTlv;

    commissioningDataTlv = GetCommissioningData();
    VerifyOrExit(commissioningDataTlv != nullptr);

    rval = MeshCoP::Tlv::FindTlv(commissioningDataTlv->GetValue(), commissioningDataTlv->GetLength(), aType);

exit:
    return rval;
}

bool LeaderBase::IsJoiningEnabled(void) const
{
    const MeshCoP::Tlv *steeringData;
    bool                rval = false;

    VerifyOrExit(GetCommissioningDataSubTlv(MeshCoP::Tlv::kBorderAgentLocator) != nullptr);

    steeringData = GetCommissioningDataSubTlv(MeshCoP::Tlv::kSteeringData);
    VerifyOrExit(steeringData != nullptr);

    for (int i = 0; i < steeringData->GetLength(); i++)
    {
        if (steeringData->GetValue()[i] != 0)
        {
            ExitNow(rval = true);
        }
    }

exit:
    return rval;
}

void LeaderBase::RemoveCommissioningData(void)
{
    CommissioningDataTlv *tlv = GetCommissioningData();

    VerifyOrExit(tlv != nullptr);
    RemoveTlv(tlv);

exit:
    return;
}

Error LeaderBase::SteeringDataCheck(const FilterIndexes &aFilterIndexes) const
{
    Error                 error = kErrorNone;
    const MeshCoP::Tlv   *steeringDataTlv;
    MeshCoP::SteeringData steeringData;

    steeringDataTlv = GetCommissioningDataSubTlv(MeshCoP::Tlv::kSteeringData);
    VerifyOrExit(steeringDataTlv != nullptr, error = kErrorInvalidState);

    As<MeshCoP::SteeringDataTlv>(steeringDataTlv)->CopyTo(steeringData);

    VerifyOrExit(steeringData.Contains(aFilterIndexes), error = kErrorNotFound);

exit:
    return error;
}

Error LeaderBase::SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const
{
    FilterIndexes   filterIndexes;
    Mac::ExtAddress joinerId;

    MeshCoP::ComputeJoinerId(aEui64, joinerId);
    MeshCoP::SteeringData::CalculateHashBitIndexes(joinerId, filterIndexes);

    return SteeringDataCheck(filterIndexes);
}

Error LeaderBase::SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const
{
    FilterIndexes filterIndexes;

    MeshCoP::SteeringData::CalculateHashBitIndexes(aDiscerner, filterIndexes);

    return SteeringDataCheck(filterIndexes);
}

void LeaderBase::SignalNetDataChanged(void)
{
    mMaxLength = Max(mMaxLength, GetLength());
    Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
}

} // namespace NetworkData
} // namespace ot
