/*
 *
 *    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 "DnssdImpl.h"
#include "lib/dnssd/platform/Dnssd.h"

#include <esp_err.h>
#include <lwip/ip4_addr.h>
#include <lwip/ip6_addr.h>

#include "platform/CHIPDeviceLayer.h"
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

namespace {

static constexpr uint32_t kTimeoutMilli = 3000;
static constexpr size_t kMaxResults     = 20;

} // namespace

namespace chip {
namespace Dnssd {

struct MdnsQuery
{
    GenericContext * ctx;
    MdnsQuery * next;
};

static MdnsQuery * sQueryList = nullptr;
void MdnsQueryNotifier(mdns_search_once_t * searchHandle);

CHIP_ERROR AddQueryList(GenericContext * ctx)
{
    MdnsQuery * ret = static_cast<MdnsQuery *>(chip::Platform::MemoryAlloc(sizeof(MdnsQuery)));
    if (ret == nullptr)
    {
        ChipLogError(DeviceLayer, "Failed to alloc memory for MdnsQuery");
        return CHIP_ERROR_NO_MEMORY;
    }
    ret->ctx   = ctx;
    ret->next  = sQueryList;
    sQueryList = ret;
    return CHIP_NO_ERROR;
}

GenericContext * FindMdnsQuery(mdns_search_once_t * searchHandle)
{
    MdnsQuery * current = sQueryList;
    while (current)
    {
        if (current->ctx && current->ctx->mSearchHandle == searchHandle)
        {
            return current->ctx;
        }
        current = current->next;
    }
    return nullptr;
}

CHIP_ERROR RemoveMdnsQuery(GenericContext * ctx)
{
    MdnsQuery * current = sQueryList;
    MdnsQuery * front   = nullptr;

    VerifyOrReturnError(ctx != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    while (current)
    {
        if (current->ctx == ctx)
        {
            break;
        }
        front   = current;
        current = current->next;
    }
    if (!current)
    {
        return CHIP_ERROR_NOT_FOUND;
    }
    if (front)
    {
        front->next = current->next;
    }
    else
    {
        sQueryList = current->next;
    }
    if (current->ctx->mContextType == ContextType::Browse)
    {
        chip::Platform::Delete(reinterpret_cast<BrowseContext *>(current->ctx));
    }
    else if (ctx->mContextType == ContextType::Resolve)
    {
        chip::Platform::Delete(reinterpret_cast<ResolveContext *>(current->ctx));
    }
    chip::Platform::MemoryFree(current);
    return CHIP_NO_ERROR;
}

CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    esp_err_t espError;

    espError = mdns_init();
    VerifyOrExit(espError == ESP_OK, error = CHIP_ERROR_INTERNAL);

exit:
    if (espError != ESP_OK)
    {
        ChipLogError(DeviceLayer, "esp mdns internal error: %s", esp_err_to_name(espError));
    }
    initCallback(context, error);

    return error;
}

void ChipDnssdShutdown() {}

static const char * GetProtocolString(DnssdServiceProtocol protocol)
{
    return protocol == DnssdServiceProtocol::kDnssdProtocolTcp ? "_tcp" : "_udp";
}

CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context)
{
    CHIP_ERROR error        = CHIP_NO_ERROR;
    mdns_txt_item_t * items = nullptr;
    esp_err_t espError;

    if (strcmp(service->mHostName, "") != 0)
    {
        VerifyOrExit(mdns_hostname_set(service->mHostName) == ESP_OK, error = CHIP_ERROR_INTERNAL);
    }

    VerifyOrExit(service->mTextEntrySize <= UINT8_MAX, error = CHIP_ERROR_INVALID_ARGUMENT);
    if (service->mTextEntries)
    {
        items = static_cast<mdns_txt_item_t *>(chip::Platform::MemoryCalloc(service->mTextEntrySize, sizeof(mdns_txt_item_t)));
        VerifyOrExit(items != nullptr, error = CHIP_ERROR_NO_MEMORY);
        for (size_t i = 0; i < service->mTextEntrySize; i++)
        {
            items[i].key = service->mTextEntries[i].mKey;
            // Unfortunately ESP mdns stack doesn't support arbitrary binary data
            items[i].value = reinterpret_cast<const char *>(service->mTextEntries[i].mData);
        }
    }

    espError = mdns_service_add(service->mName, service->mType, GetProtocolString(service->mProtocol), service->mPort, items,
                                service->mTextEntrySize);
    // The mdns_service_add will return error if we try to add an existing service
    if (espError != ESP_OK && espError != ESP_ERR_NO_MEM)
    {
        espError = mdns_service_txt_set(service->mType, GetProtocolString(service->mProtocol), items,
                                        static_cast<uint8_t>(service->mTextEntrySize));
    }
    VerifyOrExit(espError == ESP_OK, error = CHIP_ERROR_INTERNAL);

exit:
    if (items != nullptr)
    {
        chip::Platform::MemoryFree(items);
    }

    return error;
}

CHIP_ERROR ChipDnssdRemoveServices()
{
    mdns_service_remove("_matter", "_tcp");
    mdns_service_remove("_matterc", "_udp");
    return CHIP_NO_ERROR;
}

CHIP_ERROR ChipDnssdFinalizeServiceUpdate()
{
    return CHIP_NO_ERROR;
}

Inet::IPAddressType MapAddressType(mdns_ip_protocol_t ip_protocol)
{
    switch (ip_protocol)
    {
#if INET_CONFIG_ENABLE_IPV4
    case MDNS_IP_PROTOCOL_V4:
        return Inet::IPAddressType::kIPv4;
#endif
    case MDNS_IP_PROTOCOL_V6:
        return Inet::IPAddressType::kIPv6;
    default:
        return Inet::IPAddressType::kAny;
    }
}

TextEntry * GetTextEntry(mdns_txt_item_t * txt_array, uint8_t * txt_value_len, size_t txt_count)
{
    if (txt_count == 0 || txt_array == NULL)
    {
        return NULL;
    }
    TextEntry * ret = static_cast<TextEntry *>(chip::Platform::MemoryCalloc(txt_count, sizeof(TextEntry)));
    if (ret)
    {
        for (size_t TextEntryIndex = 0; TextEntryIndex < txt_count; ++TextEntryIndex)
        {
            ret[TextEntryIndex].mKey      = txt_array[TextEntryIndex].key;
            ret[TextEntryIndex].mData     = reinterpret_cast<const uint8_t *>(txt_array[TextEntryIndex].value);
            ret[TextEntryIndex].mDataSize = txt_value_len[TextEntryIndex];
        }
    }
    return ret;
}

CHIP_ERROR GetIPAddress(Inet::IPAddress & outIPAddress, mdns_ip_addr_t * mdnsIPAddr)
{
    if (!mdnsIPAddr)
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    if (mdnsIPAddr->addr.type == ESP_IPADDR_TYPE_V6)
    {
        memcpy(outIPAddress.Addr, mdnsIPAddr->addr.u_addr.ip6.addr, sizeof(mdnsIPAddr->addr.u_addr.ip6.addr));
    }
    else if (mdnsIPAddr->addr.type == ESP_IPADDR_TYPE_V4)
    {
        outIPAddress.Addr[0] = 0;
        outIPAddress.Addr[1] = 0;
        outIPAddress.Addr[2] = htonl(0xFFFF);
        outIPAddress.Addr[3] = mdnsIPAddr->addr.u_addr.ip4.addr;
    }
    else
    {
        outIPAddress = Inet::IPAddress::Any;
    }
    return CHIP_NO_ERROR;
}

size_t GetResultSize(mdns_result_t * result)
{
    size_t ret = 0;
    while (result)
    {
        ret++;
        result = result->next;
    }
    return ret;
}

CHIP_ERROR OnBrowseDone(BrowseContext * ctx)
{
    CHIP_ERROR error              = CHIP_NO_ERROR;
    mdns_result_t * currentResult = nullptr;
    size_t servicesIndex          = 0;
    VerifyOrExit(ctx && ctx->mBrowseCb, error = CHIP_ERROR_INVALID_ARGUMENT);
    if (ctx->mResult)
    {
        ctx->mServiceSize = GetResultSize(ctx->mResult);
        if (ctx->mServiceSize > 0)
        {
            ctx->mServices = static_cast<DnssdService *>(chip::Platform::MemoryCalloc(ctx->mServiceSize, sizeof(DnssdService)));
            if (!ctx->mServices)
            {
                ChipLogError(DeviceLayer, "Failed to alloc memory for Dnssd services");
                ctx->mServiceSize = 0;
                error             = CHIP_ERROR_NO_MEMORY;
                ExitNow();
            }
            currentResult = ctx->mResult;
            servicesIndex = 0;
            while (currentResult)
            {
                strncpy(ctx->mServices[servicesIndex].mName, currentResult->instance_name,
                        strnlen(currentResult->instance_name, Common::kInstanceNameMaxLength));
                strncpy(ctx->mServices[servicesIndex].mHostName, currentResult->hostname,
                        strnlen(currentResult->hostname, kHostNameMaxLength));
                strncpy(ctx->mServices[servicesIndex].mType, currentResult->service_type,
                        strnlen(currentResult->service_type, kDnssdTypeMaxSize));
                ctx->mServices[servicesIndex].mProtocol      = ctx->mProtocol;
                ctx->mServices[servicesIndex].mAddressType   = MapAddressType(currentResult->ip_protocol);
                ctx->mServices[servicesIndex].mTransportType = ctx->mAddressType;
                ctx->mServices[servicesIndex].mPort          = currentResult->port;
                ctx->mServices[servicesIndex].mInterface     = ctx->mInterfaceId;
                ctx->mServices[servicesIndex].mTextEntries =
                    GetTextEntry(currentResult->txt, currentResult->txt_value_len, currentResult->txt_count);
                ctx->mServices[servicesIndex].mTextEntrySize = currentResult->txt_count;
                ctx->mServices[servicesIndex].mSubTypes      = NULL;
                ctx->mServices[servicesIndex].mSubTypeSize   = 0;
                if (currentResult->addr)
                {
                    Inet::IPAddress IPAddr;
                    error = GetIPAddress(IPAddr, currentResult->addr);
                    SuccessOrExit(error);
                    ctx->mServices[servicesIndex].mAddress.SetValue(IPAddr);
                }
                currentResult = currentResult->next;
                servicesIndex++;
            }
        }
    }
exit:
    ctx->mBrowseCb(ctx->mCbContext, ctx->mServices, ctx->mServiceSize, error);
    return RemoveMdnsQuery(reinterpret_cast<GenericContext *>(ctx));
}

size_t GetAddressCount(mdns_ip_addr_t * addr)
{
    size_t ret = 0;
    while (addr)
    {
        ret++;
        addr = addr->next;
    }
    return ret;
}

CHIP_ERROR OnResolveQuerySrvDone(ResolveContext * ctx)
{
    CHIP_ERROR error    = CHIP_NO_ERROR;
    size_t addressIndex = 0;

    VerifyOrExit(ctx && ctx->mResolveCb, error = CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrExit(ctx->mService == nullptr && ctx->mResolveState == ResolveContext::ResolveState::QuerySrv,
                 error = CHIP_ERROR_INCORRECT_STATE);
    if (ctx->mResult)
    {
        ctx->mService = static_cast<DnssdService *>(chip::Platform::MemoryAlloc(sizeof(DnssdService)));
        VerifyOrExit(ctx->mService != nullptr, error = CHIP_ERROR_NO_MEMORY);
        strncpy(ctx->mService->mName, ctx->mResult->instance_name,
                strnlen(ctx->mResult->instance_name, Common::kInstanceNameMaxLength));
        strncpy(ctx->mService->mHostName, ctx->mResult->hostname, strnlen(ctx->mResult->hostname, kHostNameMaxLength));
        strncpy(ctx->mService->mType, ctx->mResult->service_type, strnlen(ctx->mResult->service_type, kDnssdTypeMaxSize));
        ctx->mService->mProtocol      = ctx->mProtocol;
        ctx->mService->mAddressType   = MapAddressType(ctx->mResult->ip_protocol);
        ctx->mService->mTransportType = ctx->mService->mAddressType;
        ctx->mService->mPort          = ctx->mResult->port;
        ctx->mService->mInterface     = ctx->mInterfaceId;
        ctx->mService->mSubTypes      = nullptr;
        ctx->mService->mSubTypeSize   = 0;

        if (ctx->mResult->addr)
        {
            ctx->mAddressCount = GetAddressCount(ctx->mResult->addr);
            if (ctx->mAddressCount > 0)
            {
                ctx->mAddresses =
                    static_cast<Inet::IPAddress *>(chip::Platform::MemoryCalloc(ctx->mAddressCount, sizeof(Inet::IPAddress)));
                if (ctx->mAddresses == nullptr)
                {
                    ChipLogError(DeviceLayer, "Failed to alloc memory for addresses");
                    error              = CHIP_ERROR_NO_MEMORY;
                    ctx->mAddressCount = 0;
                    ExitNow();
                }
                auto * addr = ctx->mResult->addr;
                while (addr)
                {
                    GetIPAddress(ctx->mAddresses[addressIndex], addr);
                    addressIndex++;
                    addr = addr->next;
                }
            }
            else
            {
                ctx->mAddresses    = nullptr;
                ctx->mAddressCount = 0;
            }
        }
    }
exit:
    if (error != CHIP_NO_ERROR)
    {
        ctx->mResolveCb(ctx->mCbContext, nullptr, Span<Inet::IPAddress>(nullptr, 0), error);
        RemoveMdnsQuery(reinterpret_cast<GenericContext *>(ctx));
        return error;
    }
    mdns_query_results_free(ctx->mResult);
    mdns_query_async_delete(ctx->mSearchHandle);
    ctx->mResult       = nullptr;
    ctx->mResolveState = ResolveContext::ResolveState::QueryTxt;
    // then query the text entries
    ctx->mSearchHandle = mdns_query_async_new(ctx->mInstanceName, ctx->mType, GetProtocolString(ctx->mProtocol), MDNS_TYPE_TXT,
                                              kTimeoutMilli, kMaxResults, MdnsQueryNotifier);
    return CHIP_NO_ERROR;
}

CHIP_ERROR OnResolveQueryTxtDone(ResolveContext * ctx)
{
    CHIP_ERROR error = CHIP_NO_ERROR;

    VerifyOrExit(ctx && ctx->mResolveCb, error = CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrExit(ctx->mService && ctx->mResolveState == ResolveContext::ResolveState::QueryTxt, error = CHIP_ERROR_INCORRECT_STATE);
    if (ctx->mResult)
    {
        ctx->mService->mTextEntries   = GetTextEntry(ctx->mResult->txt, ctx->mResult->txt_value_len, ctx->mResult->txt_count);
        ctx->mService->mTextEntrySize = ctx->mResult->txt_count;
    }
    else
    {
        ctx->mService->mTextEntries   = nullptr;
        ctx->mService->mTextEntrySize = 0;
    }
exit:
    if (error != CHIP_NO_ERROR)
    {
        ctx->mResolveCb(ctx->mCbContext, nullptr, Span<Inet::IPAddress>(nullptr, 0), error);
    }
    else
    {
        ctx->mResolveCb(ctx->mCbContext, ctx->mService, Span<Inet::IPAddress>(ctx->mAddresses, ctx->mAddressCount), error);
    }
    RemoveMdnsQuery(reinterpret_cast<GenericContext *>(ctx));
    return error;
}

void MdnsQueryDone(intptr_t context)
{
    if (!context)
    {
        return;
    }
    mdns_search_once_t * searchHandle = reinterpret_cast<mdns_search_once_t *>(context);
    GenericContext * ctx              = FindMdnsQuery(searchHandle);
    if (mdns_query_async_get_results(searchHandle, kTimeoutMilli, &(ctx->mResult)))
    {
        if (ctx->mContextType == ContextType::Browse)
        {
            OnBrowseDone(reinterpret_cast<BrowseContext *>(ctx));
        }
        else if (ctx->mContextType == ContextType::Resolve)
        {
            ResolveContext * resolveCtx = reinterpret_cast<ResolveContext *>(ctx);
            if (resolveCtx->mResolveState == ResolveContext::ResolveState::QuerySrv)
            {
                OnResolveQuerySrvDone(resolveCtx);
            }
            else if (resolveCtx->mResolveState == ResolveContext::ResolveState::QueryTxt)
            {
                OnResolveQueryTxtDone(resolveCtx);
            }
        }
    }
}

void MdnsQueryNotifier(mdns_search_once_t * searchHandle)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(MdnsQueryDone, reinterpret_cast<intptr_t>(searchHandle));
}

CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType,
                           chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    mdns_search_once_t * searchHandle =
        mdns_query_async_new(NULL, type, GetProtocolString(protocol), MDNS_TYPE_PTR, kTimeoutMilli, kMaxResults, MdnsQueryNotifier);
    BrowseContext * ctx =
        chip::Platform::New<BrowseContext>(type, protocol, interface, searchHandle, addressType, callback, context);
    if (!ctx)
    {
        ChipLogError(DeviceLayer, "Failed to alloc memory for browse context");
        mdns_query_async_delete(searchHandle);
        return CHIP_ERROR_NO_MEMORY;
    }
    error = AddQueryList(reinterpret_cast<GenericContext *>(ctx));
    if (error != CHIP_NO_ERROR)
    {
        chip::Platform::Delete(ctx);
    }
    return error;
}

CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback,
                            void * context)
{
    CHIP_ERROR error                  = CHIP_NO_ERROR;
    mdns_search_once_t * searchHandle = mdns_query_async_new(service->mName, service->mType, GetProtocolString(service->mProtocol),
                                                             MDNS_TYPE_SRV, kTimeoutMilli, kMaxResults, MdnsQueryNotifier);
    ResolveContext * ctx              = chip::Platform::New<ResolveContext>(service, interface, searchHandle, callback, context);
    if (!ctx)
    {
        ChipLogError(DeviceLayer, "Failed to alloc memory for resolve context");
        mdns_query_async_delete(searchHandle);
        return CHIP_ERROR_NO_MEMORY;
    }
    error = AddQueryList(reinterpret_cast<GenericContext *>(ctx));
    if (error != CHIP_NO_ERROR)
    {
        chip::Platform::Delete(ctx);
    }
    return error;
}

} // namespace Dnssd
} // namespace chip
