namespace MaksIT.LTO.Backup.Shared.Models; public abstract class PathBase { public required string Path { get; set; } } public class LocalPath : PathBase { } public class PasswordCredentials { public required string Username { get; set; } public required string Password { get; set; } } public class RemotePath : PathBase { public PasswordCredentials? PasswordCredentials { get; set; } public required string Protocol { get; set; } } public class WorkingFolder { public LocalPath? LocalPath { get; set; } public RemotePath? RemotePath { get; set; } } /// /// UScheduler-compatible calendar (empty month/weekday = all; times are UTC HH:mm). /// public class BackupSchedule { public List RunMonth { get; set; } = []; public List RunWeekday { get; set; } = []; public List RunTime { get; set; } = []; public int MinIntervalMinutes { get; set; } = 10; } /// /// Cartridge associated with a library backup job for rotation by last-used time. /// public class BackupTape { public required string Barcode { get; set; } public DateTimeOffset? LastUsedUtc { get; set; } } /// /// Ordered wave of backup jobs sharing one schedule (Worker runs aggregations, not per-job calendars). /// public class BackupAggregation { public required string Name { get; set; } public List JobNames { get; set; } = []; public BackupSchedule? Schedule { get; set; } public bool Disabled { get; set; } public DateTimeOffset? LastRunUtc { get; set; } } public class BackupItem { public required string Name { get; set; } /// /// Standalone / single-tape MAM label. Library jobs use . /// public string Barcode { get; set; } = string.Empty; public required WorkingFolder Source { get; set; } public required WorkingFolder Destination { get; set; } public required string LTOGen { get; set; } /// /// Overwrite replaces the cartridge from BOT. Append adds another FM-separated set. /// public string WriteMode { get; set; } = BackupWriteModes.Overwrite.Name; /// /// Library media pool (oldest first). /// public List Tapes { get; set; } = []; /// /// When true, aggregations skip this job. /// public bool Disabled { get; set; } } public class EmulatorLibraryOptions { public int SlotCount { get; set; } = 24; public int DriveCount { get; set; } = 2; public int IePortCount { get; set; } = 1; } public class EmulatorOptions { public string DataDirectory { get; set; } = ".\\emulator-data"; public EmulatorLibraryOptions Library { get; set; } = new(); } public class ServiceOptions { public string ServiceName { get; set; } = "MaksIT.LTO.Backup"; public string Description { get; set; } = "Schedules LTO library backup aggregations using barcode media pools."; /// /// Optional path to the Worker executable for UI lifecycle control. Empty = resolve next to UI / default name. /// public string ExecutablePath { get; set; } = string.Empty; } public class Configuration { public string DeviceMode { get; set; } = DeviceModes.Physical.Name; /// /// StandaloneDrive = tape drive only. TapeLibrary = changer inventory/move + drive bays. /// public string Topology { get; set; } = DeviceTopologies.StandaloneDrive.Name; public string TapePath { get; set; } = "\\\\.\\Tape0"; public string LibraryPath { get; set; } = "\\\\.\\Changer0"; public int WriteDelay { get; set; } = 100; /// /// When true, restore aborts on the first file checksum mismatch instead of only logging a warning. /// public bool FailFastOnChecksumMismatch { get; set; } = true; public List Backups { get; set; } = []; public List Aggregations { get; set; } = []; public EmulatorOptions Emulator { get; set; } = new(); public ServiceOptions Service { get; set; } = new(); public bool IsEmulated => DeviceModes.Matches(DeviceMode, DeviceModes.Emulated); public bool IsTapeLibrary => DeviceTopologies.Matches(Topology, DeviceTopologies.TapeLibrary); public bool IsStandaloneDrive => DeviceTopologies.Matches(Topology, DeviceTopologies.StandaloneDrive); }