using System.Collections.Frozen;
using System.Collections.ObjectModel;
using System.Net;
using System.Net.NetworkInformation;
using skyscraper5.Docsis.AnnexC;
using skyscraper5.Docsis.MacManagement;

namespace skyscraper5.Docsis;

public class NullDocsisEventHandler : IDocsisEventHandler
{
    private HashSet<PhysicalAddress> participants;
    private uint? timing;
    private Dictionary<PhysicalAddress, IPAddress> knownIps;
    
    public void OnParticipantDetected(PhysicalAddress pa)
    {
        if (participants == null)
            participants = new HashSet<PhysicalAddress>();

        participants.Add(pa);
    }

    public void OnCmtsTimestamp(PhysicalAddress source, uint timing)
    {
        OnParticipantDetected(source);
        this.timing = timing;
    }

    public void OnUpstreamChannel(UpstreamChannelDescriptor mmm)
    {
        if (_queue == null)
            _queue = new Queue<object>();
        
        _queue.Enqueue(mmm);
    }

    public void OnDownstreamChannel(PhysicalAddress physicalAddress, MacDomainDescriptor.DownstreamActiveChannel downstreamActiveChannel)
    {
        if (_queue == null)
            _queue = new Queue<object>();
        
        _queue.Enqueue(downstreamActiveChannel);
    }

    public void OnLearnedIpFromMac(PhysicalAddress arpHeaderSenderHardwareAddress, IPAddress arpHeaderSenderProtocolAddress)
    {
        if (knownIps == null)
            knownIps = new Dictionary<PhysicalAddress, IPAddress>();
        
        knownIps.Add(arpHeaderSenderHardwareAddress, arpHeaderSenderProtocolAddress);
    }

    public void OnKeyManagementResponse(PrivacyKeyManagementResponse privacyKeyManagementResponse)
    {
        if (_queue == null)
            _queue = new Queue<object>();
        
        _queue.Enqueue(privacyKeyManagementResponse);
    }

    public void OnDynamicServiceAddition(ushort transactionId, byte confirmationCode,
        CommonTlvEncodingObject tlvEncodedInformation)
    {
        if (_queue == null)
            _queue = new Queue<object>();
        
        _queue.Enqueue(tlvEncodedInformation);
    }

    private Queue<object> _queue;

    public Queue<object> GetQueue()
    {
        return _queue;
    }

    public HashSet<PhysicalAddress> GetParticipants()
    {
        return participants;
    }

    public uint GetTiming()
    {
        return timing.Value;
    }

    public ReadOnlyDictionary<PhysicalAddress, IPAddress> GetKnownIps()
    {
        return knownIps.AsReadOnly();
    }
}
