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

#pragma once

#include <cstddef>
#include <cstdint>

#include <lib/core/Optional.h>
#include <lib/core/PeerId.h>
#include <lib/dnssd/Resolver.h>
#include <lib/dnssd/minimal_mdns/core/HeapQName.h>
#include <lib/support/Variant.h>
#include <system/SystemClock.h>

namespace mdns {
namespace Minimal {

/// Keeps track of active resolve attempts
///
/// Maintains a list of 'pending mdns resolve queries' and provides operations
/// for:
///    - add/remove to the list
///    - figuring out a 'next query time' for items in the list
///    - iterating through the 'schedule now' items of the list
///
class ActiveResolveAttempts
{
public:
    static constexpr size_t kRetryQueueSize                      = 4;
    static constexpr chip::System::Clock::Timeout kMaxRetryDelay = chip::System::Clock::Seconds16(16);

    struct ScheduledAttempt
    {
        struct Browse
        {
            Browse(const chip::Dnssd::DiscoveryFilter discoveryFilter, const chip::Dnssd::DiscoveryType discoveryType) :
                filter(discoveryFilter), type(discoveryType)
            {}
            chip::Dnssd::DiscoveryFilter filter;
            chip::Dnssd::DiscoveryType type;
        };

        struct Resolve
        {
            chip::PeerId peerId;

            Resolve(chip::PeerId id) : peerId(id) {}
        };

        struct IpResolve
        {
            HeapQName hostName;
            IpResolve(HeapQName && host) : hostName(std::move(host)) {}
        };

        ScheduledAttempt() {}
        ScheduledAttempt(const chip::PeerId & peer, bool first) :
            resolveData(chip::InPlaceTemplateType<Resolve>(), peer), firstSend(first)
        {}
        ScheduledAttempt(const chip::Dnssd::DiscoveryFilter discoveryFilter, const chip::Dnssd::DiscoveryType type, bool first) :
            resolveData(chip::InPlaceTemplateType<Browse>(), discoveryFilter, type), firstSend(first)
        {}

        ScheduledAttempt(IpResolve && ipResolve, bool first) :
            resolveData(chip::InPlaceTemplateType<IpResolve>(), ipResolve), firstSend(first)
        {}

        bool operator==(const ScheduledAttempt & other) const { return Matches(other) && other.firstSend == firstSend; }
        bool Matches(const ScheduledAttempt & other) const
        {
            if (!resolveData.Valid())
            {
                return !other.resolveData.Valid();
            }

            if (resolveData.Is<Browse>())
            {
                if (!other.resolveData.Is<Browse>())
                {
                    return false;
                }

                auto & a = resolveData.Get<Browse>();
                auto & b = other.resolveData.Get<Browse>();
                return (a.filter == b.filter && a.type == b.type);
            }

            if (resolveData.Is<Resolve>())
            {
                if (!other.resolveData.Is<Resolve>())
                {
                    return false;
                }
                auto & a = resolveData.Get<Resolve>();
                auto & b = other.resolveData.Get<Resolve>();

                return a.peerId == b.peerId;
            }

            if (resolveData.Is<IpResolve>())
            {
                if (!other.resolveData.Is<IpResolve>())
                {
                    return false;
                }
                auto & a = resolveData.Get<IpResolve>();
                auto & b = other.resolveData.Get<IpResolve>();

                return a.hostName == b.hostName;
            }
            return false;
        }

        bool MatchesIpResolve(SerializedQNameIterator hostName) const
        {
            return resolveData.Is<IpResolve>() && (hostName == resolveData.Get<IpResolve>().hostName.Content());
        }
        bool Matches(const chip::PeerId & peer) const
        {
            return resolveData.Is<Resolve>() && (resolveData.Get<Resolve>().peerId == peer);
        }
        bool Matches(const chip::Dnssd::DiscoveredNodeData & data) const
        {
            if (!resolveData.Is<Browse>())
            {
                return false;
            }

            auto & browse = resolveData.Get<Browse>();

            // TODO: we should mark returned node data based on the query
            if (browse.type != chip::Dnssd::DiscoveryType::kCommissionableNode)
            {
                // We don't currently have markers in the returned DiscoveredNodeData to differentiate these, so assume all returned
                // packets match
                return true;
            }
            switch (browse.filter.type)
            {
            case chip::Dnssd::DiscoveryFilterType::kNone:
                return true;
            case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator:
                return browse.filter.code == static_cast<uint64_t>((data.commissionData.longDiscriminator >> 8) & 0x0F);
            case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator:
                return browse.filter.code == data.commissionData.longDiscriminator;
            case chip::Dnssd::DiscoveryFilterType::kVendorId:
                return browse.filter.code == data.commissionData.vendorId;
            case chip::Dnssd::DiscoveryFilterType::kDeviceType:
                return browse.filter.code == data.commissionData.deviceType;
            case chip::Dnssd::DiscoveryFilterType::kCommissioningMode:
                return browse.filter.code == data.commissionData.commissioningMode;
            case chip::Dnssd::DiscoveryFilterType::kInstanceName:
                return strncmp(browse.filter.instanceName, data.commissionData.instanceName,
                               chip::Dnssd::Commission::kInstanceNameMaxLength + 1) == 0;
            case chip::Dnssd::DiscoveryFilterType::kCommissioner:
            case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId:
            default:
                // These are for other discovery types.
                return false;
            }
        }

        bool IsEmpty() const { return !resolveData.Valid(); }
        bool IsResolve() const { return resolveData.Is<Resolve>(); }
        bool IsBrowse() const { return resolveData.Is<Browse>(); }
        bool IsIpResolve() const { return resolveData.Is<IpResolve>(); }
        void Clear() { resolveData = DataType(); }

        const Browse & BrowseData() const { return resolveData.Get<Browse>(); }
        const Resolve & ResolveData() const { return resolveData.Get<Resolve>(); }
        const IpResolve & IpResolveData() const { return resolveData.Get<IpResolve>(); }

        using DataType = chip::Variant<Browse, Resolve, IpResolve>;

        DataType resolveData;

        // First packet send is marked separately: minMDNS logic can choose
        // to first send a unicast query followed by a multicast one.
        bool firstSend = false;
    };

    ActiveResolveAttempts(chip::System::Clock::ClockBase * clock) : mClock(clock) { Reset(); }

    /// Clear out the internal queue
    void Reset();

    /// Mark a resolution as a success, removing it from the internal list
    void Complete(const chip::PeerId & peerId);
    void Complete(const chip::Dnssd::DiscoveredNodeData & data);
    void CompleteIpResolution(SerializedQNameIterator targetHostName);

    /// Mark all browse-type scheduled attemptes as a success, removing them
    /// from the internal list.
    CHIP_ERROR CompleteAllBrowses();

    /// Mark that a resolution is pending, adding it to the internal list
    ///
    /// Once this complete, this peer id will be returned immediately
    /// by NextScheduled (potentially with others as well)
    void MarkPending(const chip::PeerId & peerId);
    void MarkPending(const chip::Dnssd::DiscoveryFilter & filter, const chip::Dnssd::DiscoveryType type);
    void MarkPending(ScheduledAttempt::IpResolve && resolve);

    // Get minimum time until the next pending reply is required.
    //
    // Returns missing if no actively tracked elements exist.
    chip::Optional<chip::System::Clock::Timeout> GetTimeUntilNextExpectedResponse() const;

    // Get the peer Id that needs scheduling for a query
    //
    // Assumes that the resolution is being sent and will apply internal
    // query logic. This means:
    //  - internal tracking of 'next due time' will updated as 'request sent
    //    now'
    //  - there is NO sorting implied by this call. Returned value will be
    //    any peer that needs a new request sent
    chip::Optional<ScheduledAttempt> NextScheduled();

    /// Check if any of the pending queries are for the given host name for
    /// IP resolution.
    bool IsWaitingForIpResolutionFor(SerializedQNameIterator hostName) const;

private:
    struct RetryEntry
    {
        ScheduledAttempt attempt;
        // When a reply is expected for this item
        chip::System::Clock::Timestamp queryDueTime;

        // Next expected delay for sending if reply is not reached by
        // 'queryDueTimeMs'
        //
        // Based on RFC 6762 expectations are:
        //    - the interval between the first two queries MUST be at least
        //      one second
        //    - the intervals between successive queries MUST increase by at
        //      least a factor of two
        chip::System::Clock::Timeout nextRetryDelay = chip::System::Clock::Seconds16(1);
    };
    void MarkPending(ScheduledAttempt && attempt);
    chip::System::Clock::ClockBase * mClock;
    RetryEntry mRetryQueue[kRetryQueueSize];
};

} // namespace Minimal
} // namespace mdns
