using Microsoft.EntityFrameworkCore; using System; using System.Linq; using System.Text.Json; using System.Security.Principal; using System.Threading.Tasks; namespace Inventory.Core { public class DatabaseUpdater { private readonly InventoryContext _db; private readonly SystemInfoCollector _collector; private readonly HealthMonitor _healthMonitor; private readonly ConsumerType _consumerType; private static readonly TimeZoneInfo ManilaTimeZone = GetManilaTimeZone(); private string? _existingPrinters; private static TimeZoneInfo GetManilaTimeZone() { try { return TimeZoneInfo.FindSystemTimeZoneById("Asia/Manila"); // IANA ID for Linux/macOS } catch (TimeZoneNotFoundException) { return TimeZoneInfo.FindSystemTimeZoneById("Singapore Standard Time"); // Windows ID } } public DatabaseUpdater(InventoryContext db, SystemInfoCollector collector, HealthMonitor healthMonitor, ConsumerType consumerType) { _db = db; _collector = collector; _healthMonitor = healthMonitor; _consumerType = consumerType; } public async Task UpsertDevice() { // --- Step 1: Data Collection --- string? localIdentifier = GetLocalIdentifier(); if (string.IsNullOrWhiteSpace(localIdentifier)) { return; } var healthReport = _healthMonitor.CollectHealthMetrics(); // --- Step 2: Data Persistence --- var existingDevice = await _db.Devices.FirstOrDefaultAsync(d => d.HardwareIdentifier == localIdentifier); // The agent service (running as SYSTEM) cannot access user-specific printer info. // We only collect and update printer data if we are NOT running as the system service. if (existingDevice != null) { // Update existing device _existingPrinters = existingDevice.Printers; UpdateDeviceProperties(existingDevice, healthReport); } else { // Create new device var newDevice = new Device(); newDevice.HardwareIdentifier = localIdentifier; UpdateDeviceProperties(newDevice, healthReport); // Update all properties _db.Devices.Add(newDevice); } await _db.SaveChangesAsync(); } private void UpdateDeviceProperties(Device device, HealthMetricsReport healthReport) { var (ipAddresses, macAddress) = _collector.GetNetworkInfo(); device.ComputerName = _collector.GetComputerName(); device.DeviceType = _collector.GetDeviceType(); device.SerialNumber = _collector.GetSystemSerialNumber(); device.MotherboardSerialNumber = _collector.GetMotherboardSerialNumber(); device.SystemUUID = _collector.GetSystemUUID(); device.Processor = _collector.GetProcessor(); device.RAM = _collector.GetTotalRAM(); device.GPUs = JsonSerializer.Serialize(_collector.GetGPUs()); // Save as JSON array device.HasOpticalDrive = _collector.HasOpticalDrive(); device.OSVersion = _collector.GetOSVersion(); device.OsInstallDate = _collector.GetOSInstallDate(); device.OSLicenseKey = _collector.GetOSLicenseKey(); device.IPAddress = JsonSerializer.Serialize(ipAddresses); device.MACAddress = macAddress; // Health Metrics device.CpuTemperature = healthReport.CpuTemp; device.GpuTemperature = healthReport.GpuTemp; device.BatteryHealthPercent = healthReport.BatteryHealth; device.Monitors = JsonSerializer.Serialize(_collector.GetMonitors()); device.StorageDevices = JsonSerializer.Serialize(_collector.GetStorage()); device.DriveHealth = JsonSerializer.Serialize(healthReport.DriveHealth); device.HealthMetrics = JsonSerializer.Serialize(healthReport); device.LocalAdmins = JsonSerializer.Serialize(_collector.GetLocalAdmins()); if (_consumerType == ConsumerType.AdminTool) { // Only the Admin Tool should ever collect and save printer information. device.Printers = JsonSerializer.Serialize(_collector.GetPrinters()); } else if (!string.IsNullOrEmpty(_existingPrinters)) { // If running as Agent, preserve existing printer data if available. device.Printers = _existingPrinters; } device.LastSeen = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, ManilaTimeZone); } public string? GetLocalIdentifier() { string? motherboardSerial = _collector.GetMotherboardSerialNumber(); if (IsValidIdentifier(motherboardSerial)) { return motherboardSerial; } string? systemUuid = _collector.GetSystemUUID(); if (IsValidIdentifier(systemUuid)) { return systemUuid; } var (_, macAddress) = _collector.GetNetworkInfo(); if (IsValidIdentifier(macAddress)) { return macAddress; } var computerName = _collector.GetComputerName(); if (IsValidIdentifier(computerName)) { return computerName; } return null; } private bool IsValidIdentifier(string? identifier) { return !string.IsNullOrWhiteSpace(identifier) && !identifier.Equals("Unknown", StringComparison.OrdinalIgnoreCase) && !identifier.Equals("N/A", StringComparison.OrdinalIgnoreCase) && !identifier.Equals("Not Available", StringComparison.OrdinalIgnoreCase) && !identifier.Equals("To be filled by O.E.M.", StringComparison.OrdinalIgnoreCase) && !identifier.Equals("Default string", StringComparison.OrdinalIgnoreCase); } } }