/*
 *
 *    Copyright (c) 2020 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.
 */

#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/internal/DeviceNetworkInfo.h>

#include <app/AttributeAccessInterface.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/Linux/NetworkCommissioningDriver.h>
#include <platform/PlatformManager.h>
#include <platform/ThreadStackManager.h>

#include <nlbyteorder.hpp>
#include <nlio-byteorder.hpp>
#include <nlio.hpp>

using namespace ::chip::app;
using namespace ::chip::app::Clusters;
using namespace chip::DeviceLayer::NetworkCommissioning;

namespace chip {
namespace DeviceLayer {

ThreadStackManagerImpl ThreadStackManagerImpl::sInstance;

constexpr char ThreadStackManagerImpl::kDBusOpenThreadService[];
constexpr char ThreadStackManagerImpl::kDBusOpenThreadObjectPath[];

constexpr char ThreadStackManagerImpl::kOpenthreadDeviceRoleDisabled[];
constexpr char ThreadStackManagerImpl::kOpenthreadDeviceRoleDetached[];
constexpr char ThreadStackManagerImpl::kOpenthreadDeviceRoleChild[];
constexpr char ThreadStackManagerImpl::kOpenthreadDeviceRoleRouter[];
constexpr char ThreadStackManagerImpl::kOpenthreadDeviceRoleLeader[];

constexpr char ThreadStackManagerImpl::kPropertyDeviceRole[];

ThreadStackManagerImpl::ThreadStackManagerImpl() : mAttached(false) {}

CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack()
{
    std::unique_ptr<GError, GErrorDeleter> err;
    mProxy.reset(openthread_io_openthread_border_router_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
                                                                               kDBusOpenThreadService, kDBusOpenThreadObjectPath,
                                                                               nullptr, &MakeUniquePointerReceiver(err).Get()));
    if (!mProxy)
    {
        ChipLogError(DeviceLayer, "openthread: failed to create openthread dbus proxy %s", err ? err->message : "unknown error");
        return CHIP_ERROR_INTERNAL;
    }

    g_signal_connect(mProxy.get(), "g-properties-changed", G_CALLBACK(OnDbusPropertiesChanged), this);

    // If get property is called inside dbus thread (we are going to make it so), XXX_get_XXX can be used instead of XXX_dup_XXX
    // which is a little bit faster and the returned object doesn't need to be freed. Same for all following get properties.
    std::unique_ptr<gchar, GFree> role(openthread_io_openthread_border_router_dup_device_role(mProxy.get()));
    if (role)
    {
        ThreadDevcieRoleChangedHandler(role.get());
    }

    return CHIP_NO_ERROR;
}

void ThreadStackManagerImpl::OnDbusPropertiesChanged(OpenthreadIoOpenthreadBorderRouter * proxy, GVariant * changed_properties,
                                                     const gchar * const * invalidated_properties, gpointer user_data)
{
    ThreadStackManagerImpl * me = reinterpret_cast<ThreadStackManagerImpl *>(user_data);
    if (g_variant_n_children(changed_properties) > 0)
    {
        const gchar * key;
        GVariant * value;

        std::unique_ptr<GVariantIter, GVariantIterDeleter> iter;
        g_variant_get(changed_properties, "a{sv}", &MakeUniquePointerReceiver(iter).Get());
        if (!iter)
            return;
        while (g_variant_iter_loop(iter.get(), "{&sv}", &key, &value))
        {
            if (key == nullptr || value == nullptr)
                continue;
            // ownership of key and value is still holding by the iter
            DeviceLayer::SystemLayer().ScheduleLambda([me]() { me->_UpdateNetworkStatus(); });

            if (strcmp(key, kPropertyDeviceRole) == 0)
            {
                const gchar * value_str = g_variant_get_string(value, nullptr);
                if (value_str == nullptr)
                    continue;
                ChipLogProgress(DeviceLayer, "Thread role changed to: %s", value_str);
                me->ThreadDevcieRoleChangedHandler(value_str);
            }
        }
    }
}

void ThreadStackManagerImpl::ThreadDevcieRoleChangedHandler(const gchar * role)
{
    bool attached = strcmp(role, kOpenthreadDeviceRoleDetached) != 0 && strcmp(role, kOpenthreadDeviceRoleDisabled) != 0;

    ChipDeviceEvent event = ChipDeviceEvent{};

    if (attached != mAttached)
    {
        event.Type = DeviceEventType::kThreadConnectivityChange;
        event.ThreadConnectivityChange.Result =
            attached ? ConnectivityChange::kConnectivity_Established : ConnectivityChange::kConnectivity_Lost;
        CHIP_ERROR status = PlatformMgr().PostEvent(&event);
        if (status != CHIP_NO_ERROR)
        {
            ChipLogError(DeviceLayer, "Failed to post thread connectivity change: %" CHIP_ERROR_FORMAT, status.Format());
        }
    }
    mAttached = attached;

    event.Type                          = DeviceEventType::kThreadStateChange;
    event.ThreadStateChange.RoleChanged = true;
    CHIP_ERROR status                   = PlatformMgr().PostEvent(&event);
    if (status != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Failed to post thread state change: %" CHIP_ERROR_FORMAT, status.Format());
    }
}

void ThreadStackManagerImpl::_ProcessThreadActivity() {}

bool ThreadStackManagerImpl::_HaveRouteToAddress(const Inet::IPAddress & destAddr)
{
    if (!mProxy || !_IsThreadAttached())
    {
        return false;
    }
    if (destAddr.IsIPv6LinkLocal())
    {
        return true;
    }

    std::unique_ptr<GVariant, GVariantDeleter> routes(openthread_io_openthread_border_router_dup_external_routes(mProxy.get()));
    if (!routes)
        return false;

    if (g_variant_n_children(routes.get()) > 0)
    {
        std::unique_ptr<GVariantIter, GVariantIterDeleter> iter;
        g_variant_get(routes.get(), "av", &MakeUniquePointerReceiver(iter).Get());
        if (!iter)
            return false;

        GVariant * route;
        while (g_variant_iter_loop(iter.get(), "&v", &route))
        {
            if (route == nullptr)
                continue;
            std::unique_ptr<GVariant, GVariantDeleter> prefix;
            guint16 rloc16;
            guchar preference;
            gboolean stable;
            gboolean nextHopIsThisDevice;
            g_variant_get(route, "(&vqybb)", &MakeUniquePointerReceiver(prefix).Get(), &rloc16, &preference, &stable,
                          &nextHopIsThisDevice);
            if (!prefix)
                continue;

            std::unique_ptr<GVariant, GVariantDeleter> address;
            guchar prefixLength;
            g_variant_get(prefix.get(), "(&vy)", &MakeUniquePointerReceiver(address).Get(), &prefixLength);
            if (!address)
                continue;

            GBytes * bytes = g_variant_get_data_as_bytes(address.get()); // the ownership still hold by address
            if (bytes == nullptr)
                continue;
            gsize size;
            gconstpointer data = g_bytes_get_data(bytes, &size);
            if (data == nullptr)
                continue;
            if (size != sizeof(struct in6_addr))
                continue;

            Inet::IPPrefix p;
            p.IPAddr = Inet::IPAddress(*reinterpret_cast<const struct in6_addr *>(data));
            p.Length = prefixLength;

            if (p.MatchAddress(destAddr))
            {
                return true;
            }
        }
    }

    return false;
}

void ThreadStackManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
{
    (void) event;
    // The otbr-agent processes the Thread state handling by itself so there
    // isn't much to do in the Chip stack.
}

CHIP_ERROR ThreadStackManagerImpl::_SetThreadProvision(ByteSpan netInfo)
{
    VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnError(Thread::OperationalDataset::IsValid(netInfo), CHIP_ERROR_INVALID_ARGUMENT);

    {
        std::unique_ptr<GBytes, GBytesDeleter> bytes(g_bytes_new(netInfo.data(), netInfo.size()));
        if (!bytes)
            return CHIP_ERROR_NO_MEMORY;
        std::unique_ptr<GVariant, GVariantDeleter> value(
            g_variant_new_from_bytes(G_VARIANT_TYPE_BYTESTRING, bytes.release(), true));
        if (!value)
            return CHIP_ERROR_NO_MEMORY;
        openthread_io_openthread_border_router_set_active_dataset_tlvs(mProxy.get(), value.release());
    }

    // post an event alerting other subsystems about change in provisioning state
    ChipDeviceEvent event;
    event.Type                                           = DeviceEventType::kServiceProvisioningChange;
    event.ServiceProvisioningChange.IsServiceProvisioned = true;
    return PlatformMgr().PostEvent(&event);
}

CHIP_ERROR ThreadStackManagerImpl::_GetThreadProvision(Thread::OperationalDataset & dataset)
{
    VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);

    {
        std::unique_ptr<GError, GErrorDeleter> err;

        std::unique_ptr<GVariant, GVariantDeleter> response(
            g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get",
                                   g_variant_new("(ss)", "io.openthread.BorderRouter", "ActiveDatasetTlvs"), G_DBUS_CALL_FLAGS_NONE,
                                   -1, nullptr, &MakeUniquePointerReceiver(err).Get()));

        if (err)
        {
            ChipLogError(DeviceLayer, "openthread: failed to read ActiveDatasetTlvs property: %s", err->message);
            return CHIP_ERROR_INTERNAL;
        }

        // Note: The actual value is wrapped by a GVariant container, wrapped in another GVariant with tuple type.

        if (response == nullptr)
        {
            return CHIP_ERROR_KEY_NOT_FOUND;
        }

        std::unique_ptr<GVariant, GVariantDeleter> tupleContent(g_variant_get_child_value(response.get(), 0));

        if (tupleContent == nullptr)
        {
            return CHIP_ERROR_KEY_NOT_FOUND;
        }

        std::unique_ptr<GVariant, GVariantDeleter> value(g_variant_get_variant(tupleContent.get()));

        if (value == nullptr)
        {
            return CHIP_ERROR_KEY_NOT_FOUND;
        }

        gsize size;
        const uint8_t * data = reinterpret_cast<const uint8_t *>(g_variant_get_fixed_array(value.get(), &size, sizeof(guchar)));
        ReturnErrorOnFailure(mDataset.Init(ByteSpan(data, size)));
    }

    dataset.Init(mDataset.AsByteSpan());

    return CHIP_NO_ERROR;
}

bool ThreadStackManagerImpl::_IsThreadProvisioned()
{
    return static_cast<Thread::OperationalDataset &>(mDataset).IsCommissioned();
}

void ThreadStackManagerImpl::_ErasePersistentInfo()
{
    static_cast<Thread::OperationalDataset &>(mDataset).Clear();
}

bool ThreadStackManagerImpl::_IsThreadEnabled()
{
    VerifyOrReturnError(mProxy, false);

    std::unique_ptr<GError, GErrorDeleter> err;

    std::unique_ptr<GVariant, GVariantDeleter> response(
        g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get",
                               g_variant_new("(ss)", "io.openthread.BorderRouter", "DeviceRole"), G_DBUS_CALL_FLAGS_NONE, -1,
                               nullptr, &MakeUniquePointerReceiver(err).Get()));

    if (err)
    {
        ChipLogError(DeviceLayer, "openthread: failed to read DeviceRole property: %s", err->message);
        return false;
    }

    if (response == nullptr)
    {
        return false;
    }

    std::unique_ptr<GVariant, GVariantDeleter> tupleContent(g_variant_get_child_value(response.get(), 0));

    if (tupleContent == nullptr)
    {
        return false;
    }

    std::unique_ptr<GVariant, GVariantDeleter> value(g_variant_get_variant(tupleContent.get()));

    if (value == nullptr)
    {
        return false;
    }

    const gchar * role = g_variant_get_string(value.get(), nullptr);

    if (role == nullptr)
    {
        return false;
    }

    return (strcmp(role, kOpenthreadDeviceRoleDisabled) != 0);
}

bool ThreadStackManagerImpl::_IsThreadAttached() const
{
    return mAttached;
}

CHIP_ERROR ThreadStackManagerImpl::_SetThreadEnabled(bool val)
{
    VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);
    if (val)
    {
        openthread_io_openthread_border_router_call_attach(mProxy.get(), nullptr, _OnThreadBrAttachFinished, this);
    }
    else
    {
        std::unique_ptr<GError, GErrorDeleter> err;
        gboolean result =
            openthread_io_openthread_border_router_call_reset_sync(mProxy.get(), nullptr, &MakeUniquePointerReceiver(err).Get());
        if (err)
        {
            ChipLogError(DeviceLayer, "openthread: _SetThreadEnabled calling %s failed: %s", "Reset", err->message);
            return CHIP_ERROR_INTERNAL;
        }

        if (!result)
        {
            ChipLogError(DeviceLayer, "openthread: _SetThreadEnabled calling %s failed: %s", "Reset", "return false");
            return CHIP_ERROR_INTERNAL;
        }
    }
    return CHIP_NO_ERROR;
}

void ThreadStackManagerImpl::_OnThreadBrAttachFinished(GObject * source_object, GAsyncResult * res, gpointer user_data)
{
    ThreadStackManagerImpl * this_ = reinterpret_cast<ThreadStackManagerImpl *>(user_data);
    std::unique_ptr<GVariant, GVariantDeleter> attachRes;
    std::unique_ptr<GError, GErrorDeleter> err;
    {
        gboolean result = openthread_io_openthread_border_router_call_attach_finish(this_->mProxy.get(), res,
                                                                                    &MakeUniquePointerReceiver(err).Get());
        if (!result)
        {
            ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s",
                         err == nullptr ? "unknown error" : err->message);
            DeviceLayer::SystemLayer().ScheduleLambda([this_]() {
                if (this_->mpConnectCallback != nullptr)
                {
                    // TODO: Replace this with actual thread attach result.
                    this_->mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), 0);
                    this_->mpConnectCallback = nullptr;
                }
            });
        }
        else
        {
            DeviceLayer::SystemLayer().ScheduleLambda([this_]() {
                if (this_->mpConnectCallback != nullptr)
                {
                    // TODO: Replace this with actual thread attach result.
                    this_->mpConnectCallback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0);
                    this_->mpConnectCallback = nullptr;
                }
            });
        }
    }
}

ConnectivityManager::ThreadDeviceType ThreadStackManagerImpl::_GetThreadDeviceType()
{
    ConnectivityManager::ThreadDeviceType type = ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
    if (!mProxy)
    {
        ChipLogError(DeviceLayer, "Cannot get device role with Thread api client: %s", "");
        return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
    }

    std::unique_ptr<gchar, GFree> role(openthread_io_openthread_border_router_dup_device_role(mProxy.get()));
    if (!role)
        return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
    if (strcmp(role.get(), kOpenthreadDeviceRoleDetached) == 0 || strcmp(role.get(), kOpenthreadDeviceRoleDisabled) == 0)
    {
        return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
    }
    if (strcmp(role.get(), kOpenthreadDeviceRoleChild) == 0)
    {
        std::unique_ptr<GVariant, GVariantDeleter> linkMode(openthread_io_openthread_border_router_dup_link_mode(mProxy.get()));
        if (!linkMode)
            return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
        gboolean rx_on_when_idle;
        gboolean device_type;
        gboolean network_data;
        g_variant_get(linkMode.get(), "(bbb)", &rx_on_when_idle, &device_type, &network_data);
        if (!rx_on_when_idle)
        {
            type = ConnectivityManager::ThreadDeviceType::kThreadDeviceType_SleepyEndDevice;
        }
        else
        {
            type = device_type ? ConnectivityManager::ThreadDeviceType::kThreadDeviceType_FullEndDevice
                               : ConnectivityManager::ThreadDeviceType::kThreadDeviceType_MinimalEndDevice;
        }
        return type;
    }
    if (strcmp(role.get(), kOpenthreadDeviceRoleLeader) == 0 || strcmp(role.get(), kOpenthreadDeviceRoleRouter) == 0)
    {
        return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_Router;
    }

    ChipLogError(DeviceLayer, "Unknown Thread role: %s", role.get());
    return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported;
}

CHIP_ERROR ThreadStackManagerImpl::_SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType)
{
    gboolean rx_on_when_idle = true;
    gboolean device_type     = true;
    gboolean network_data    = true;
    VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);
    if (deviceType == ConnectivityManager::ThreadDeviceType::kThreadDeviceType_MinimalEndDevice)
    {
        network_data = false;
    }
    else if (deviceType == ConnectivityManager::ThreadDeviceType::kThreadDeviceType_SleepyEndDevice)
    {
        rx_on_when_idle = false;
        network_data    = false;
    }

    if (!network_data)
    {
        std::unique_ptr<GVariant, GVariantDeleter> linkMode(g_variant_new("(bbb)", rx_on_when_idle, device_type, network_data));
        if (!linkMode)
            return CHIP_ERROR_NO_MEMORY;
        openthread_io_openthread_border_router_set_link_mode(mProxy.get(), linkMode.release());
    }

    return CHIP_NO_ERROR;
}

#if CHIP_DEVICE_CONFIG_ENABLE_SED
CHIP_ERROR ThreadStackManagerImpl::_GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig)
{
    (void) intervalsConfig;

    ChipLogError(DeviceLayer, "SED intervals config is not supported on linux");
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig)
{
    (void) intervalsConfig;

    ChipLogError(DeviceLayer, "SED intervals config is not supported on linux");
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_RequestSEDActiveMode(bool onOff)
{
    (void) onOff;

    ChipLogError(DeviceLayer, "SED intervals config is not supported on linux");
    return CHIP_ERROR_NOT_IMPLEMENTED;
}
#endif

bool ThreadStackManagerImpl::_HaveMeshConnectivity()
{
    // TODO: Remove Weave legacy APIs
    // For a leader with a child, the child is considered to have mesh connectivity
    // and the leader is not, which is a very confusing definition.
    // This API is Weave legacy and should be removed.

    ChipLogError(DeviceLayer, "HaveMeshConnectivity has confusing behavior and shouldn't be called");
    return false;
}

CHIP_ERROR ThreadStackManagerImpl::_GetAndLogThreadStatsCounters()
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_GetAndLogThreadTopologyMinimal()
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_GetAndLogThreadTopologyFull()
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_GetPrimary802154MACAddress(uint8_t * buf)
{
    VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);
    guint64 extAddr = openthread_io_openthread_border_router_get_extended_address(mProxy.get());

    for (size_t i = 0; i < sizeof(extAddr); i++)
    {
        buf[sizeof(uint64_t) - i - 1] = (extAddr & UINT8_MAX);
        extAddr >>= CHAR_BIT;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR ThreadStackManagerImpl::_GetExternalIPv6Address(chip::Inet::IPAddress & addr)
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_GetPollPeriod(uint32_t & buf)
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_JoinerStart()
{
    // TODO: Remove Weave legacy APIs
    return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_StartThreadScan(ThreadDriver::ScanCallback * callback)
{
    // There is another ongoing scan request, reject the new one.
    VerifyOrReturnError(mpScanCallback == nullptr, CHIP_ERROR_INCORRECT_STATE);
    mpScanCallback = callback;
    openthread_io_openthread_border_router_call_scan(mProxy.get(), nullptr, _OnNetworkScanFinished, this);
    return CHIP_NO_ERROR;
}

void ThreadStackManagerImpl::_OnNetworkScanFinished(GObject * source_object, GAsyncResult * res, gpointer user_data)
{
    ThreadStackManagerImpl * this_ = reinterpret_cast<ThreadStackManagerImpl *>(user_data);
    this_->_OnNetworkScanFinished(res);
}

void ThreadStackManagerImpl::_OnNetworkScanFinished(GAsyncResult * res)
{
    std::unique_ptr<GVariant, GVariantDeleter> scan_result;
    std::unique_ptr<GError, GErrorDeleter> err;
    {
        gboolean result = openthread_io_openthread_border_router_call_scan_finish(
            mProxy.get(), &MakeUniquePointerReceiver(scan_result).Get(), res, &MakeUniquePointerReceiver(err).Get());
        if (!result)
        {
            ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s",
                         err == nullptr ? "unknown error" : err->message);
            DeviceLayer::SystemLayer().ScheduleLambda([this]() {
                if (mpScanCallback != nullptr)
                {
                    LinuxScanResponseIterator<ThreadScanResponse> iter(nullptr);
                    mpScanCallback->OnFinished(Status::kUnknownError, CharSpan(), &iter);
                }
                mpScanCallback = nullptr;
            });
        }
    }

    std::vector<NetworkCommissioning::ThreadScanResponse> * scanResult =
        new std::vector<NetworkCommissioning::ThreadScanResponse>();

    if (g_variant_n_children(scan_result.get()) > 0)
    {
        std::unique_ptr<GVariantIter, GVariantIterDeleter> iter;
        g_variant_get(scan_result.get(), "a(tstayqqyyyybb)", &MakeUniquePointerReceiver(iter).Get());
        if (!iter)
        {
            delete scanResult;
            return;
        }

        guint64 ext_address;
        const gchar * network_name;
        guint64 ext_panid;
        const gchar * steering_data;
        guint16 panid;
        guint16 joiner_udp_port;
        guint8 channel;
        guint8 rssi;
        guint8 lqi;
        guint8 version;
        gboolean is_native;
        gboolean is_joinable;

        while (g_variant_iter_loop(iter.get(), "(tstayqqyyyybb)", &ext_address, &network_name, &ext_panid, &steering_data, &panid,
                                   &joiner_udp_port, &channel, &rssi, &lqi, &version, &is_native, &is_joinable))
        {
            ChipLogProgress(DeviceLayer,
                            "Thread Network: %s (%016" PRIx64 ") ExtPanId(%016" PRIx64 ") RSSI %u LQI %u"
                            " Version %u",
                            network_name, ext_address, ext_panid, rssi, lqi, version);
            NetworkCommissioning::ThreadScanResponse networkScanned;
            networkScanned.panId         = panid;
            networkScanned.extendedPanId = ext_panid;
            size_t networkNameLen        = strlen(network_name);
            if (networkNameLen > 16)
            {
                ChipLogProgress(DeviceLayer, "Network name is too long, ignore it.");
                continue;
            }
            networkScanned.networkNameLen = static_cast<uint8_t>(networkNameLen);
            memcpy(networkScanned.networkName, network_name, networkNameLen);
            networkScanned.channel         = channel;
            networkScanned.version         = version;
            networkScanned.extendedAddress = 0;
            networkScanned.rssi            = rssi;
            networkScanned.lqi             = lqi;

            scanResult->push_back(networkScanned);
        }
    }

    DeviceLayer::SystemLayer().ScheduleLambda([this, scanResult]() {
        // Note: We cannot post a event in ScheduleLambda since std::vector is not trivial copiable. This results in the use of
        // const_cast but should be fine for almost all cases, since we actually handled the ownership of this element to this
        // lambda.
        if (mpScanCallback != nullptr)
        {
            LinuxScanResponseIterator<NetworkCommissioning::ThreadScanResponse> iter(
                const_cast<std::vector<ThreadScanResponse> *>(scanResult));
            mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter);
            mpScanCallback = nullptr;
        }
        delete const_cast<std::vector<ThreadScanResponse> *>(scanResult);
    });
}

void ThreadStackManagerImpl::_ResetThreadNetworkDiagnosticsCounts() {}

CHIP_ERROR ThreadStackManagerImpl::_WriteThreadNetworkDiagnosticAttributeToTlv(AttributeId attributeId,
                                                                               app::AttributeValueEncoder & encoder)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    switch (attributeId)
    {
    case ThreadNetworkDiagnostics::Attributes::NeighborTableList::Id:
    case ThreadNetworkDiagnostics::Attributes::RouteTableList::Id:
    case ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::Id:
        err = encoder.EncodeEmptyList();
        break;
    case ThreadNetworkDiagnostics::Attributes::Channel::Id:
    case ThreadNetworkDiagnostics::Attributes::RoutingRole::Id:
    case ThreadNetworkDiagnostics::Attributes::NetworkName::Id:
    case ThreadNetworkDiagnostics::Attributes::PanId::Id:
    case ThreadNetworkDiagnostics::Attributes::ExtendedPanId::Id:
    case ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::Id:
    case ThreadNetworkDiagnostics::Attributes::PartitionId::Id:
    case ThreadNetworkDiagnostics::Attributes::Weighting::Id:
    case ThreadNetworkDiagnostics::Attributes::DataVersion::Id:
    case ThreadNetworkDiagnostics::Attributes::StableDataVersion::Id:
    case ThreadNetworkDiagnostics::Attributes::LeaderRouterId::Id:
    case ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::Id:
    case ThreadNetworkDiagnostics::Attributes::PendingTimestamp::Id:
    case ThreadNetworkDiagnostics::Attributes::Delay::Id:
    case ThreadNetworkDiagnostics::Attributes::ChannelPage0Mask::Id:
    case ThreadNetworkDiagnostics::Attributes::SecurityPolicy::Id:
    case ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::Id:
        err = encoder.EncodeNull();
        break;
    case ThreadNetworkDiagnostics::Attributes::OverrunCount::Id:
        err = encoder.Encode(static_cast<uint64_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::ChildRoleCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RouterRoleCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::ParentChangeCount::Id:
        err = encoder.Encode(static_cast<uint16_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxTotalCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxUnicastCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxAckedCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxDataCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxDataPollCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxBeaconCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxOtherCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxRetryCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxTotalCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxUnicastCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxDataCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxDataPollCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxBeaconCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxOtherCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrSecCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    case ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::Id:
        err = encoder.Encode(static_cast<uint32_t>(0));
        break;
    default:
        err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
        break;
    }

    return err;
}

CHIP_ERROR
ThreadStackManagerImpl::_AttachToThreadNetwork(const Thread::OperationalDataset & dataset,
                                               NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback)
{
    // Reset the previously set callback since it will never be called in case incorrect dataset was supplied.
    mpConnectCallback = nullptr;
    ReturnErrorOnFailure(DeviceLayer::ThreadStackMgr().SetThreadEnabled(false));
    ReturnErrorOnFailure(DeviceLayer::ThreadStackMgr().SetThreadProvision(dataset.AsByteSpan()));

    if (dataset.IsCommissioned())
    {
        ReturnErrorOnFailure(DeviceLayer::ThreadStackMgr().SetThreadEnabled(true));
        mpConnectCallback = callback;
    }

    return CHIP_NO_ERROR;
}

void ThreadStackManagerImpl::_UpdateNetworkStatus()
{
    // Thread is not enabled, then we are not trying to connect to the network.
    VerifyOrReturn(IsThreadEnabled() && mpStatusChangeCallback != nullptr);

    Thread::OperationalDataset dataset;
    uint8_t extpanid[Thread::kSizeExtendedPanId];

    // If we have not provisioned any Thread network, return the status from last network scan,
    // If we have provisioned a network, we assume the ot-br-posix is activitely connecting to that network.
    CHIP_ERROR err = ThreadStackMgrImpl().GetThreadProvision(dataset);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Failed to get configured network when updating network status: %s", err.AsString());
        return;
    }

    // The Thread network is not enabled, but has a different extended pan id.
    VerifyOrReturn(dataset.GetExtendedPanId(extpanid) == CHIP_NO_ERROR);

    // We have already connected to the network, thus return success.
    if (ThreadStackMgrImpl().IsThreadAttached())
    {
        mpStatusChangeCallback->OnNetworkingStatusChange(Status::kSuccess, MakeOptional(ByteSpan(extpanid)), NullOptional);
    }
    else
    {
        mpStatusChangeCallback->OnNetworkingStatusChange(Status::kNetworkNotFound, MakeOptional(ByteSpan(extpanid)), NullOptional);
    }
}

ThreadStackManager & ThreadStackMgr()
{
    return chip::DeviceLayer::ThreadStackManagerImpl::sInstance;
}

ThreadStackManagerImpl & ThreadStackMgrImpl()
{
    return chip::DeviceLayer::ThreadStackManagerImpl::sInstance;
}

} // namespace DeviceLayer
} // namespace chip
