using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Intrinsics.Arm;
using System.Text;
using PacketDotNet;
using SharpPcap;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace LogCap.Common
{
    public class LogExecute
    {
        public static string FilterStr = ReadConfig.Instance.get_monitor_filter;
        public Task Execute(int i)
        {
            Console.WriteLine("过滤的： " + FilterStr);
            var device2 = CaptureDeviceList.Instance[i];

            PubRepository.liveDevice = device2;
            int readTimeoutMilliseconds = 2000;


            // Register our handler function to the 'packet arrival' event
            device2.OnPacketArrival +=
                        new PacketArrivalEventHandler(device_OnPacketArrival);

            // Open the devices for capturing
            device2.Open(DeviceModes.Promiscuous, readTimeoutMilliseconds);

            // set the filters
            device2.Filter = FilterStr;

            Console.WriteLine("device2.Filter {0} ", device2.Filter);

            Console.WriteLine();
            Console.WriteLine("-- Listening on {0} {1}, hit 'Enter' to stop...",
                device2.Name, device2.Description);

            // Start the capturing process
            //device1.StartCapture();
            device2.StartCapture();

            return Task.CompletedTask;
        }

        public static long TotalCountGlobal = 0;
        private static void device_OnPacketArrival(object sender, PacketCapture e)
        {
            try
            {

                var rawPacket = e.GetPacket();
                var time = rawPacket.Timeval.Date;
                var len = rawPacket.Data.Length;
                var udd = rawPacket.Data;
                //Console.WriteLine("{0}:{1}:{2},{3} Len={4}",
                //    time.Hour, time.Minute, time.Second, time.Millisecond, len);
                Packet p = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);

                //var ethernetPacket = (EthernetPacket)p;

                //// 获取源MAC和目标MAC地址
                //string sourceMac = ethernetPacket.SourceHardwareAddress.ToString();
                //[IPv4Packet: SourceAddress= 172.16.4.152,
                //DestinationAddress = 172.16.4.152,
                //HeaderLength = 5, Protocol = Udp, TimeToLive = 128][UDPPacket: SourcePort= 55966, DestinationPort = 1314]

                var q = p.PayloadData;
                var pff = p.PayloadPacket;
                IPAddress SourceAddress = ((PacketDotNet.IPv4Packet)pff).SourceAddress;
                ushort SourcePort = ((PacketDotNet.UdpPacket)((PacketDotNet.IPPacket)pff).PayloadPacket).SourcePort;
                var DestinationAddress = ((PacketDotNet.IPv4Packet)pff).DestinationAddress;
                ushort DestinationPort = ((PacketDotNet.UdpPacket)((PacketDotNet.IPPacket)pff).PayloadPacket).DestinationPort;

                int pport = ReadConfig.Instance.monitor_server_port;
                string iip = ReadConfig.Instance.monitor_server_ip;


                if (SourcePort != pport && !iip.Equals(SourceAddress.ToString()))
                {
                    Interlocked.Increment(ref TotalCountGlobal);
                }
                //上行和下行如何区分

                //如果目标IP和端口是 3339和服务器IP的话 就是上行，其它都是下行
                byte[] Data = ((PacketDotNet.IPPacket)pff).PayloadPacket.PayloadData;
                //ReceiverContext context = new ReceiverContext(Data);
                //context.SystemHeader = DecodeSystemHeader(context.Data);
                //string hostnumber= context.SystemHeader.Value.HostNumber.ToString();
                //028006045045
                //253007014192
                if (Data.Length > 0)
                {
                    //Console.WriteLine(p.ToString());
                    Tuple<byte[], IPAddress, ushort, IPAddress, ushort> ddd = new Tuple<byte[], IPAddress, ushort, IPAddress, ushort>(Data, SourceAddress, SourcePort, DestinationAddress, DestinationPort);
                    Task.Factory.StartNew((State) =>
                    {
                        var tf = State as Tuple<byte[], IPAddress, ushort, IPAddress, ushort>;
                        DealWithData.HandleData(tf.Item1.ToList(), tf.Item2.ToString(), tf.Item3, tf.Item4.ToString(), tf.Item5);
                    }, ddd);
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}
