using System;
using System.Collections.Generic;
using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using Ursa.Controls;
using 常用工具集.Utility.Network;
using 常用工具集.ViewModel._02网络相关;

namespace 常用工具集;

public partial class 端口扫描 : UserControl
{
    private bool stop;
    private Queue<ScanPortEntity> allScanPort;
    private object lockObj = new object();
    private object lockMsg = new object();
    public 端口扫描()
    {
        InitializeComponent();
    }
    private void UserControl_Loaded(object? sender, RoutedEventArgs e)
    {
        allScanPort = new Queue<ScanPortEntity>();
        textBox1.TextChanged += textBox1_TextChanged;
        textBox2.TextChanged += textBox2_TextChanged;
        textBox3.TextChanged += textBox3_TextChanged;
    }

    private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
    {
        textBox8.Text = textBox1.Text;
    }
    private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
    {
        textBox7.Text = textBox2.Text;
    }

    private void textBox3_TextChanged(object sender, TextChangedEventArgs e)
    {
        textBox6.Text = textBox3.Text;
    }
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        if ("停止" == button1.Content.ToString())
        {
            stop = true;
            button1.Content = "扫描";
        }
        else
        {
            //非空检测
            if (textBox1.Text.Trim().Length == 0 || textBox2.Text.Trim().Length == 0 || textBox3.Text.Trim().Length == 0 || textBox4.Text.Trim().Length == 0 || textBox5.Text.Trim().Length == 0)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            //数据范围检测
            if (Convert.ToInt32(textBox1.Text.Trim()) < 0 || Convert.ToInt32(textBox1.Text.Trim()) > 255)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            if (Convert.ToInt32(textBox2.Text.Trim()) < 0 || Convert.ToInt32(textBox2.Text.Trim()) > 255)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            if (Convert.ToInt32(textBox3.Text.Trim()) < 0 || Convert.ToInt32(textBox3.Text.Trim()) > 255)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            if (Convert.ToInt32(textBox4.Text.Trim()) < 0 || Convert.ToInt32(textBox4.Text.Trim()) > 255)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            if (Convert.ToInt32(textBox5.Text.Trim()) < 0 || Convert.ToInt32(textBox5.Text.Trim()) > 255)
            {
                MessageBox.ShowAsync("请填写正确的IP地址");
                return;
            }
            if (Convert.ToInt32(textBox5.Text.Trim()) < Convert.ToInt32(textBox4.Text.Trim()))
            {
                MessageBox.ShowAsync("结束IP不能小于起始IP");
                return;
            }
            if (textBox9.Text.Trim().Length == 0)
            {
                MessageBox.ShowAsync("请输入要扫描的端口号");
                return;
            }
            if (textBox10.Text.Trim().Length == 0)
            {
                MessageBox.ShowAsync("请输入超时时间");
                return;
            }
            int timeout = Convert.ToInt32(textBox10.Text.Trim());
            if (textBox11.Text.Trim().Length == 0)
            {
                MessageBox.ShowAsync("请输入线程数");
                return;
            }
            int threadCount = Convert.ToInt32(textBox11.Text.Trim());
            allScanPort.Clear();
            List<string> portList = new List<string>();
            string[] strPortArray = textBox9.Text.Trim().Split(',');
            foreach (string strPort in strPortArray)
            {
                try
                {
                    if (strPort.Trim().Length == 0)
                    {
                        continue;
                    }
                    if (strPort.Contains("-"))
                    {
                        string[] aa = strPort.Split('-');
                        if (aa.Length > 2)
                        {
                            MessageBox.ShowAsync("请输入正确的端口号");
                            return;
                        }
                        int startPort = Convert.ToInt32(aa[0]);
                        int endPort = Convert.ToInt32(aa[1]);
                        if (endPort < startPort)
                        {
                            MessageBox.ShowAsync("请输入正确的端口号范围");
                            return;
                        }
                        if (startPort < 0 && startPort > 65535)
                        {
                            MessageBox.ShowAsync("端口号范围应该是0-65535");
                            return;
                        }
                        if (endPort < 0 && endPort > 65535)
                        {
                            MessageBox.ShowAsync("端口号范围应该是0-65535");
                            return;
                        }
                        for (int i = startPort; i <= endPort; i++)
                        {
                            string port = Convert.ToString(i);
                            if (!portList.Contains(port))
                                portList.Add(port);
                        }

                    }
                    else if (strPort.Contains("~"))
                    {
                        string[] aa = strPort.Split('~');
                        if (aa.Length > 2)
                        {
                            MessageBox.ShowAsync("请输入正确的端口号");
                            return;
                        }
                        int startPort = Convert.ToInt32(aa[0]);
                        int endPort = Convert.ToInt32(aa[1]);
                        if (endPort < startPort)
                        {
                            MessageBox.ShowAsync("请输入正确的端口号范围");
                            return;
                        }
                        if (startPort < 0 && startPort > 65535)
                        {
                            MessageBox.ShowAsync("端口号范围应该是0-65535");
                            return;
                        }
                        if (endPort < 0 && endPort > 65535)
                        {
                            MessageBox.ShowAsync("端口号范围应该是0-65535");
                            return;
                        }
                        for (int i = startPort; i <= endPort; i++)
                        {
                            string port = Convert.ToString(i);
                            if (!portList.Contains(port))
                                portList.Add(port);
                        }
                    }
                    else
                    {
                        int startPort = Convert.ToInt32(strPort);
                        if (startPort < 0 && startPort > 65535)
                        {
                            MessageBox.ShowAsync("端口号范围应该是0-65535");
                            return;
                        }
                        string port = Convert.ToString(startPort);
                        if (!portList.Contains(port))
                            portList.Add(port);

                    }
                }
                catch
                {
                    MessageBox.ShowAsync("请输入正确的端口号");
                    return;
                }
            }
            string ipFront = textBox1.Text.Trim() + "." + textBox2.Text.Trim() + "." + textBox3.Text.Trim() + ".";
            int startIp = Convert.ToInt32(textBox4.Text.Trim());
            int endIp = Convert.ToInt32(textBox5.Text.Trim());
            for (int j = startIp; j <= endIp; j++)
            {
                string ipAddress = ipFront + j;
                foreach (string port in portList)
                {
                    ScanPortEntity entity = new ScanPortEntity();
                    entity.IP = ipAddress;
                    entity.Port = Convert.ToInt32(port);
                    allScanPort.Enqueue(entity);
                }
            }
            textBox12.Text = string.Empty;
            uiProcessBar1.Maximum = allScanPort.Count;
            uiProcessBar1.Value = 0;
            stop = false;
            button1.Content = "停止";
            for (int i = 0; i < threadCount; i++)
            {
                new Thread(StartScan).Start(timeout);
            }
        }
    }
    private void StartScan(object objTimeout)
    {
        int timeout = (int)objTimeout;
        while (!stop)
        {
            int count = 0;
            bool flag;
            ScanPortEntity entity = null;
            lock (lockObj)
            {
                try
                {
                    entity = allScanPort.Dequeue();
                    count = allScanPort.Count;
                    flag = true;
                }
                catch
                {
                    flag = false;
                }
            }
            if (!flag)
            {
                break;
            }
            Dispatcher.UIThread.Invoke(new Action(() =>
            {
                if (stop)
                    return;
                uiProcessBar1.Value = uiProcessBar1.Maximum - count;
                if (count == 0)
                {
                    allScanPort.Clear();
                    stop = true;
                    button1.Content = "扫描";
                }
            }));
            if (entity == null)
                break;
            //扫描该IP和端口
            try
            {
                TimeOutSocket tc = new TimeOutSocket(entity.IP, entity.Port, timeout);
                tc.Connect();
                //通
                Dispatcher.UIThread.Invoke(new Action(() =>
                {
                    lock (lockMsg)
                    {
                        string message = entity.IP + ":" + entity.Port;
                        textBox12.Text = textBox12.Text + message + "\r\n";
                    }
                }));
            }
            catch (Exception e)
            {
                //不通
            }
        }
    }
}

public class ScanPortEntity
{
    public ScanPortEntity() { }
    public ScanPortEntity(string ip, int port)
    {
        this.IP = ip;
        this.Port = port;
    }
    public string IP { get; set; }
    public int Port { get; set; }

}