/*
 *
 *    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.
 */

#include <chip/internal/ChipThreadWork.h>
#include <lib/dnssd/Resolver.h>
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>

#include <type_traits>

using namespace chip;
using namespace chip::Dnssd;

static_assert(std::is_same<uint32_t, ChipError::StorageType>::value, "python assumes CHIP_ERROR maps to c_uint32");

namespace {

// callback types shared with python code (see ptyhon code in chip.discovery.types)
using DiscoverSuccessCallback = void (*)(uint64_t fabricId, uint64_t nodeId, uint32_t interfaceId, const char * ip, uint16_t port);
using DiscoverFailureCallback = void (*)(uint64_t fabricId, uint64_t nodeId, ChipError::StorageType error_code);

class PythonResolverDelegate : public OperationalResolveDelegate
{
public:
    void OnOperationalNodeResolved(const ResolvedNodeData & nodeData) override
    {
        if (mSuccessCallback != nullptr)
        {
            char ipAddressBuffer[128];

            // TODO: For now, just provide addr 0, but this should really provide all and
            // allow the caller to choose.
            mSuccessCallback(                                                                            //
                nodeData.operationalData.peerId.GetCompressedFabricId(),                                 //
                nodeData.operationalData.peerId.GetNodeId(),                                             //
                nodeData.resolutionData.interfaceId.GetPlatformInterface(),                              //
                nodeData.resolutionData.ipAddress[0].ToString(ipAddressBuffer, sizeof(ipAddressBuffer)), //
                nodeData.resolutionData.port                                                             //
            );
        }
        else
        {
            ChipLogError(Controller, "Discovery success without any python callback set.");
        }
    }

    void OnOperationalNodeResolutionFailed(const PeerId & peerId, CHIP_ERROR error) override
    {
        if (mFailureCallback != nullptr)
        {
            mFailureCallback(peerId.GetCompressedFabricId(), peerId.GetNodeId(), error.AsInteger());
        }
        else
        {
            ChipLogError(Controller, "Discovery failure without any python callback set.");
        }
    }

    void SetSuccessCallback(DiscoverSuccessCallback cb) { mSuccessCallback = cb; }
    void SetFailureCallback(DiscoverFailureCallback cb) { mFailureCallback = cb; }

private:
    DiscoverSuccessCallback mSuccessCallback = nullptr;
    DiscoverFailureCallback mFailureCallback = nullptr;
}; // namespace

PythonResolverDelegate gPythonResolverDelegate;

} // namespace

extern "C" void pychip_discovery_set_callbacks(DiscoverSuccessCallback success, DiscoverFailureCallback failure)
{
    gPythonResolverDelegate.SetSuccessCallback(success);
    gPythonResolverDelegate.SetFailureCallback(failure);
}

extern "C" ChipError::StorageType pychip_discovery_resolve(uint64_t fabricId, uint64_t nodeId)
{
    CHIP_ERROR result = CHIP_NO_ERROR;

    chip::python::ChipMainThreadScheduleAndWait([&] {
        result = Resolver::Instance().Init(chip::DeviceLayer::UDPEndPointManager());
        ReturnOnFailure(result);
        Resolver::Instance().SetOperationalDelegate(&gPythonResolverDelegate);

        result = Resolver::Instance().ResolveNodeId(chip::PeerId().SetCompressedFabricId(fabricId).SetNodeId(nodeId),
                                                    chip::Inet::IPAddressType::kAny);
    });

    return result.AsInteger();
}
