using MemoryPack;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Insight.Agent.Messages
{
    [MemoryPackUnion(70, typeof(Interface))]
    [MemoryPackUnion(71, typeof(InterfaceList))]
    public partial interface IAgentMessage { }

    [MemoryPackable]
    public partial class Interface : IAgentMessage
    {
        [MemoryPackOrder(0)]
        public uint? Index { get; set; }

        [MemoryPackOrder(1)]
        public Guid? Guid { get; set; }

        [MemoryPackOrder(2)]
        public string? Mac { get; set; }

        [MemoryPackOrder(3)]
        public string? Name { get; set; }

        [MemoryPackOrder(4)]
        public string? Description { get; set; }

        [MemoryPackOrder(5)]
        public string? Manufacturer { get; set; }

        [MemoryPackOrder(6)]
        public string? Suffix { get; set; }

        [MemoryPackOrder(7)]
        public bool? Physical { get; set; }

        [MemoryPackOrder(8)]
        public NetworkInterfaceType? Type { get; set; }

        [MemoryPackOrder(9)]
        public OperationalStatus? Status { get; set; }

        [MemoryPackOrder(10)]
        public long? Speed { get; set; }

        [MemoryPackOrder(11)]
        public long? Ipv4Mtu { get; set; }

        [MemoryPackOrder(12)]
        public bool? Ipv4Dhcp { get; set; }

        [MemoryPackOrder(13)]
        public bool? Ipv4Forwarding { get; set; }

        [MemoryPackOrder(14)]
        public long? Ipv6Mtu { get; set; }

        [MemoryPackOrder(15)]
        public long? Sent { get; set; }

        [MemoryPackOrder(16)]
        public long? Received { get; set; }

        [MemoryPackOrder(17)]
        public long? IncomingPacketsDiscarded { get; set; }

        [MemoryPackOrder(18)]
        public long? IncomingPacketsWithErrors { get; set; }

        [MemoryPackOrder(19)]
        public long? IncomingUnknownProtocolPackets { get; set; }

        [MemoryPackOrder(20)]
        public long? OutgoingPacketsDiscarded { get; set; }

        [MemoryPackOrder(21)]
        public long? OutgoingPacketsWithErrors { get; set; }

        [MemoryPackOrder(22)]
        public List<Unicast>? Addresses { get; set; }

        [MemoryPackOrder(23)]
        public List<IPAddress2>? Gateways { get; set; }

        [MemoryPackOrder(24)]
        public List<IPAddress2>? Dns { get; set; }

        [MemoryPackOrder(25)]
        public List<IPAddress2>? Dhcp { get; set; }

        [MemoryPackOrder(26)]
        public List<Route>? Routes { get; set; }
    }

    [MemoryPackable(GenerateType.Collection)]
    public partial class InterfaceList : List<Interface>, IAgentMessage { }

    [MemoryPackable]
    public partial class Unicast : IAgentMessage
    {
        [MemoryPackOrder(0)]
        public IPAddress2? IpAddress { get; set; }

        [MemoryPackOrder(1)]
        public IPAddress2? Ipv4Mask { get; set; }

        [MemoryPackOrder(2)]
        public long? AddressPreferredLifetime { get; set; }

        [MemoryPackOrder(3)]
        public long? AddressValidLifetime { get; set; }

        [MemoryPackOrder(4)]
        public long? DhcpLeaseLifetime { get; set; }

        [MemoryPackOrder(5)]
        public DuplicateAddressDetectionState? DuplicateAddressDetectionState { get; set; }

        [MemoryPackOrder(6)]
        public int? PrefixLength { get; set; }

        [MemoryPackOrder(7)]
        public PrefixOrigin? PrefixOrigin { get; set; }

        [MemoryPackOrder(8)]
        public SuffixOrigin? SuffixOrigin { get; set; }
    }

    [MemoryPackable]
    public partial class Route : IAgentMessage
    {
        [MemoryPackOrder(0)]
        public uint? InterfaceIndex { get; set; }

        [MemoryPackOrder(1)]
        public IPAddress2? Destination { get; set; }

        [MemoryPackOrder(2)]
        public IPAddress2? Gateway { get; set; }

        [MemoryPackOrder(3)]
        public string? Mask { get; set; }

        [MemoryPackOrder(4)]
        public int? Metric { get; set; }
    }

    [MemoryPackable]
    public partial class IPAddress2 : IAgentMessage
    {
        [MemoryPackOrder(0)]
        public AddressFamily? AddressFamily { get; set; }

        [MemoryPackOrder(1)]
        public string? Address { get; set; }

        [MemoryPackOrder(2)]
        public bool? IsIPv6Teredo { get; set; }

        [MemoryPackOrder(3)]
        public bool? IsIPv6SiteLocal { get; set; }

        [MemoryPackOrder(4)]
        public bool? IsIPv6Multicast { get; set; }

        [MemoryPackOrder(5)]
        public bool? IsIPv6LinkLocal { get; set; }

        [MemoryPackOrder(6)]
        public bool? IsIPv4MappedToIPv6 { get; set; }

        [MemoryPackOrder(7)]
        public bool? IsIPv6UniqueLocal { get; set; }

        [MemoryPackConstructor]
        public IPAddress2()
        {

        }

        public IPAddress2(IPAddress address)
        {
            AddressFamily = address.AddressFamily;
            Address = address.ToString();
            IsIPv4MappedToIPv6 = address.IsIPv4MappedToIPv6;
            IsIPv6LinkLocal = address.IsIPv6LinkLocal;
            IsIPv6Multicast = address.IsIPv6Multicast;
            IsIPv6SiteLocal = address.IsIPv6SiteLocal;
            IsIPv6Teredo = address.IsIPv6Teredo;
            IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
        }
    }
}