using Microsoft.VisualBasic.ApplicationServices;
using Newtonsoft.Json;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace SwitchDahua
{
    public partial class Form1 : Form
    {
        private readonly HttpClient _httpClient;
        private string server, user, password, session;
        private int token;
        public Form1()
        {
            InitializeComponent();
            var handler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
            };
            server = "172.22.10.7";
            _httpClient = new HttpClient(handler);
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
            

        }

        private string CalculateMD5(string input)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);

                StringBuilder sb = new StringBuilder();
                foreach (byte b in hashBytes)
                {
                    sb.Append(b.ToString("X2"));
                }
                return sb.ToString();
            }
        }

        private async Task<string> GetSessionAsync(string server, string user, string password)
        {
            // 1. Challenge запрос
            var challengeRequest = new
            {
                method = "global.login",
                @params = new
                {
                    userName = user,
                    password = "",
                    clientType = "Web3.0"
                },
                id = 1,
                session = (string)null
            };

            string json = System.Text.Json.JsonSerializer.Serialize(challengeRequest);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync($"http://{server}/RPC2_Login", content);
            response.EnsureSuccessStatusCode();

            var responseJson = await response.Content.ReadAsStringAsync();
            using JsonDocument doc = JsonDocument.Parse(responseJson);
            var root = doc.RootElement;

            if (!root.TryGetProperty("result", out var resultProp) || resultProp.GetBoolean())
                throw new Exception("Не удалось получить challenge");

            string realm = root.GetProperty("params").GetProperty("realm").GetString();
            string random = root.GetProperty("params").GetProperty("random").GetString();
            string session = root.GetProperty("session").GetString();

            // 2. Вычисление пароля
            string pwdHash = CalculateMD5($"{user}:{realm}:{password}");
            string passHash = CalculateMD5($"{user}:{random}:{pwdHash}");

            // 3. Авторизация
            var authRequest = new
            {
                method = "global.login",
                @params = new
                {
                    userName = user,
                    clientType = "Web3.0",
                    authorityType = "Default",
                    passwordType = "Default",
                    password = passHash
                },
                id = 2,
                session = session
            };

            json = System.Text.Json.JsonSerializer.Serialize(authRequest);
            content = new StringContent(json, Encoding.UTF8, "application/json");

            response = await _httpClient.PostAsync($"http://{server}/RPC2_Login", content);
            response.EnsureSuccessStatusCode();

            responseJson = await response.Content.ReadAsStringAsync();
            using JsonDocument authDoc = JsonDocument.Parse(responseJson);
            var authRoot = authDoc.RootElement;

            if (!authRoot.TryGetProperty("result", out resultProp) || !resultProp.GetBoolean())
                throw new Exception("Ошибка авторизации");

            return authRoot.GetProperty("session").GetString();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            comboBox1.SelectionStart = 0;
            user = textBox2.Text;
            password = textBox3.Text;
            session = await GetSessionAsync(server, user, password);

            await GetLLDP();
            await GetMacTable();
            // Запрос информации о дисках
        }

        private async Task GetMacTable()
        {
            var portRequest = new
            {
                method = "PortManager.startFindMac",
                @params = new
                {
                    Condition = new object() // или конкретные условия поиска
                },
                id = 270, // Идентификатор запроса
                session // Сессия из авторизации
            };

            string json = System.Text.Json.JsonSerializer.Serialize(portRequest);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync($"http://{server}/RPC2", content);
            response.EnsureSuccessStatusCode();

            var responseJson = await response.Content.ReadAsStringAsync();
            MAC1 ListDev = JsonConvert.DeserializeObject<MAC1>(responseJson);
            token = ListDev.Params.Token;

            var MacRequest = new
            {
                method = "PortManager.doFindMac",
                @params = new
                {
                    Count = 24,
                    Offset = 0,
                    Token = token
                },
                id = 270, // Идентификатор запроса
                session // Сессия из авторизации
            };
            string json2 = System.Text.Json.JsonSerializer.Serialize(MacRequest);
            var content2 = new StringContent(json2, Encoding.UTF8, "application/json");

            var response2 = await _httpClient.PostAsync($"http://{server}/RPC2", content2);
            response2.EnsureSuccessStatusCode();

            var responseJson2 = await response2.Content.ReadAsStringAsync();
            MAC ListDev2 = JsonConvert.DeserializeObject<MAC>(responseJson2);
            var listMac = ListDev2.Params.Info;
            string txt2 = string.Empty;
            foreach (var dev in listMac)
            {
                txt2 += dev.PortID + "\t" + dev.MAC + Environment.NewLine;
            }
            textBox5.Text = txt2;
        }

        private async Task GetLLDP()
        {
            var diskRequest = new
            {
                method = "LLDPManager.getLLDPNeighborsInfo",
                @params = (object)null,
                id = 270,
                session
            };

            string json = System.Text.Json.JsonSerializer.Serialize(diskRequest);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync($"http://{server}/RPC2", content);
            response.EnsureSuccessStatusCode();

            var responseJson = await response.Content.ReadAsStringAsync();
            LLDP ListDev = JsonConvert.DeserializeObject<LLDP>(responseJson);
            var DevList = ListDev.Params;
            DevList = DevList.OrderBy(item => item.ManagerIP).ToList();
            string txt = string.Empty;
            foreach (var dev in DevList)
            {
                txt += dev.LocalInterface.Substring(dev.LocalInterface.LastIndexOf('/') + 1) + "\t" + dev.ManagerIP + Environment.NewLine;
            }
            textBox4.Text = txt;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var t = comboBox1.Items[comboBox1.SelectedIndex].ToString();
            t = t.Substring(0,t.Length - (t.Length - t.IndexOf("\t")));
            server = t;
        }
    }
}
