InventoryAgent/Inventory.Core/DatabaseUpdater.cs
2025-10-21 12:58:33 +08:00

158 lines
6.2 KiB
C#

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);
}
}
}