/*
 *
 *    Copyright (c) 2023 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 <inet/EndpointQueueFilter.h>
#include <inet/IPAddress.h>
#include <lwip/ip_addr.h>

namespace chip {
namespace Inet {

class ESP32EndpointQueueFilter : public EndpointQueueFilter
{
public:
    CHIP_ERROR SetMdnsHostName(const chip::CharSpan & hostName)
    {
        ReturnErrorCodeIf(hostName.size() != sizeof(mHostNameBuffer), CHIP_ERROR_INVALID_ARGUMENT);
        ReturnErrorCodeIf(!IsValidMdnsHostName(hostName), CHIP_ERROR_INVALID_ARGUMENT);
        memcpy(mHostNameBuffer, hostName.data(), hostName.size());
        return CHIP_NO_ERROR;
    }

    FilterOutcome FilterBeforeEnqueue(const void * endpoint, const IPPacketInfo & pktInfo,
                                      const chip::System::PacketBufferHandle & pktPayload) override
    {
        if (!IsMdnsBroadcastPacket(pktInfo))
        {
            return FilterOutcome::kAllowPacket;
        }
        // Drop the mDNS packets which don't contain 'matter' or '<device-hostname>'.
        const uint8_t matterBytes[] = { 'm', 'a', 't', 't', 'e', 'r' };
        if (PayloadContainsCaseInsensitive(pktPayload, ByteSpan(matterBytes)) ||
            PayloadContainsCaseInsensitive(pktPayload, ByteSpan(mHostNameBuffer)))
        {
            return FilterOutcome::kAllowPacket;
        }
        return FilterOutcome::kDropPacket;
    }

    FilterOutcome FilterAfterDequeue(const void * endpoint, const IPPacketInfo & pktInfo,
                                     const chip::System::PacketBufferHandle & pktPayload) override
    {
        return FilterOutcome::kAllowPacket;
    }

private:
    // TODO: Add unit tests for these static functions
    static bool IsMdnsBroadcastPacket(const IPPacketInfo & pktInfo)
    {
        if (pktInfo.DestPort == 5353)
        {
#if INET_CONFIG_ENABLE_IPV4
            ip_addr_t mdnsIPv4BroadcastAddr = IPADDR4_INIT_BYTES(224, 0, 0, 251);
            if (pktInfo.DestAddress == chip::Inet::IPAddress(mdnsIPv4BroadcastAddr))
            {
                return true;
            }
#endif
            ip_addr_t mdnsIPv6BroadcastAddr = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0xFB);
            if (pktInfo.DestAddress == chip::Inet::IPAddress(mdnsIPv6BroadcastAddr))
            {
                return true;
            }
        }
        return false;
    }

    static bool BytesCaseInsensitiveCompare(const uint8_t * buf1, const uint8_t * buf2, size_t size)
    {
        for (size_t i = 0; i < size; ++i)
        {
            uint8_t byte1 = (buf1[i] >= 'A' && buf1[i] <= 'Z') ? buf1[i] - 'A' + 'a' : buf1[i];
            uint8_t byte2 = (buf2[i] >= 'A' && buf2[i] <= 'Z') ? buf2[i] - 'A' + 'a' : buf2[i];
            if (byte1 != byte2)
            {
                return false;
            }
        }
        return true;
    }

    static bool PayloadContainsCaseInsensitive(const chip::System::PacketBufferHandle & payload, const chip::ByteSpan & byteSpan)
    {
        if (payload->HasChainedBuffer() || payload->TotalLength() < byteSpan.size())
        {
            return false;
        }
        for (size_t i = 0; i <= payload->TotalLength() - byteSpan.size(); ++i)
        {
            if (BytesCaseInsensitiveCompare(payload->Start() + i, byteSpan.data(), byteSpan.size()))
            {
                return true;
            }
        }
        return false;
    }

    static bool IsValidMdnsHostName(const chip::CharSpan & hostName)
    {
        for (size_t i = 0; i < hostName.size(); ++i)
        {
            char ch_data = *(hostName.data() + i);
            if (!((ch_data >= '0' && ch_data <= '9') || (ch_data >= 'A' && ch_data <= 'F')))
            {
                return false;
            }
        }
        return true;
    }

    uint8_t mHostNameBuffer[12] = { 0 };
};

} // namespace Inet
} // namespace chip
