using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;

namespace Insight.Agent.Network.Handlers
{
    [SupportedOSPlatform("windows")]
    public class MainboardHandler : IAgentMessageHandler<AgentSession>
    {
        public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
        {
            if (message is GetInventory)
            {
                await sender.SendAsync(GetMainboard(), cancellationToken);
            }
        }

        private static Mainboard GetMainboard()
        {
            using var searcher = new ManagementObjectSearcher
            {
                Scope = new ManagementScope(@"root\cimv2"),
                Query = new ObjectQuery("select manufacturer, product, serialnumber from win32_baseboard")
            };

            if (searcher.TryGet(out var collection) is false)
            {
                searcher.Query = new ObjectQuery("select * from win32_baseboard");

                if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
            }

            var mainboard = new Mainboard();

            using (collection)
            {
                foreach (ManagementObject @object in collection.Cast<ManagementObject>())
                {
                    var properties = @object.GetPropertyHashes();

                    mainboard.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
                    mainboard.Model = @object.GetValue<string>(properties, "product")?.Trim();
                    mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();

                    break;
                }
            }

            searcher.Query = new ObjectQuery("select manufacturer, serialnumber, smbiosbiosversion, releasedate from win32_bios");

            if (searcher.TryGet(out var collection2) is false)
            {
                searcher.Query = new ObjectQuery("select * from win32_bios");

                if (searcher.TryGet(out collection2) is false) return null;
            }

            using (collection2)
            {
                foreach (ManagementObject @object in collection2.Cast<ManagementObject>())
                {
                    var properties = @object.GetPropertyHashes();

                    mainboard.BiosManufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
                    mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
                    mainboard.BiosVersion = @object.GetValue<string>(properties, "smbiosbiosversion")?.Trim();

                    if (@object.TryGetValue<object>(properties, "releasedate", out var releasedate))
                    {
                        mainboard.BiosDate = ManagementDateTimeConverter.ToDateTime(releasedate?.ToString());
                    }

                    break;
                }
            }

            //Logger.LogWarning(JsonSerializer.Serialize(mainboard, new JsonSerializerOptions
            //{
            //    WriteIndented= true
            //}));

            return mainboard;
        }
    }
}