using RackPeek.Domain.Resources.AccessPoints; using RackPeek.Domain.Resources.Desktops; using RackPeek.Domain.Resources.Firewalls; using RackPeek.Domain.Resources.Laptops; using RackPeek.Domain.Resources.Routers; using RackPeek.Domain.Resources.Servers; using RackPeek.Domain.Resources.Services; using RackPeek.Domain.Resources.Switches; using RackPeek.Domain.Resources.SystemResources; using RackPeek.Domain.Resources.UpsUnits; namespace RackPeek.Domain.Resources; public abstract class Resource { private static readonly string[] _hardwareTypes = ["server", "switch", "firewall", "router", "accesspoint", "desktop", "laptop", "ups"]; private static readonly Dictionary _kindToPluralDictionary = new() { { "hardware", "hardware" }, { "server", "servers" }, { "switch", "switches" }, { "firewall", "firewalls" }, { "router", "routers" }, { "accesspoint", "accesspoints" }, { "desktop", "desktops" }, { "laptop", "laptops" }, { "ups", "ups" }, { "system", "systems" }, { "service", "services" } }; private static readonly Dictionary _typeToKindMap = new() { { typeof(Hardware.Hardware), "Hardware" }, { typeof(Server), "Server" }, { typeof(Switch), "Switch" }, { typeof(Firewall), "Firewall" }, { typeof(Router), "Router" }, { typeof(AccessPoint), "Accesspoint" }, { typeof(Desktop), "Desktop" }, { typeof(Laptop), "Laptop" }, { typeof(Ups), "Ups" }, { typeof(SystemResource), "System" }, { typeof(Service), "Service" } }; public string Kind { get; set; } = string.Empty; public required string Name { get; set; } public string[] Tags { get; set; } = []; public Dictionary Labels { get; set; } = new(); public string? Notes { get; set; } public List RunsOn { get; set; } = new(); public static bool IsHardware(string kind) { kind = kind.Trim().ToLower(); return kind == "hardware" || _hardwareTypes.Contains(kind); } public static string GetResourceUrl(string kind, string name) { var encoded = Uri.EscapeDataString(name); kind = kind.Trim().ToLower(); if (IsHardware(kind)) return $"resources/hardware/{encoded}"; if (kind == "system") return $"resources/systems/{encoded}"; if (kind == "service") return $"resources/services/{encoded}"; return "#"; } public static string KindToPlural(string kind) => _kindToPluralDictionary.GetValueOrDefault(kind.ToLower().Trim(), kind); public static string GetKind() where T : Resource { if (_typeToKindMap.TryGetValue(typeof(T), out var kind)) return kind; throw new InvalidOperationException( $"No kind mapping defined for type {typeof(T).Name}"); } public static bool CanRunOn(Resource parent) where T : Resource { var childKind = GetKind().ToLowerInvariant(); var parentKind = parent.Kind.ToLowerInvariant(); // Service -> System if (childKind == "service" && parentKind == "system") return true; // System -> Hardware if (childKind == "system" && parent is Hardware.Hardware) return true; // System -> System if (childKind == "system" && parent is SystemResource) return true; return false; } }