using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace CredentialManager.Models; /// /// Modello per la schedulazione dei profili Data Coupler /// public class ProfileSchedule { [Key] public int Id { get; set; } [Required] [MaxLength(100)] public string Name { get; set; } = string.Empty; [MaxLength(500)] public string? Description { get; set; } // Relazione con il profilo [Required] public int ProfileId { get; set; } [ForeignKey(nameof(ProfileId))] public virtual DataCouplerProfile Profile { get; set; } = null!; // Configurazione scheduling [Required] public bool IsEnabled { get; set; } = true; [Required] [MaxLength(20)] public string ScheduleType { get; set; } = string.Empty; // "once", "daily", "weekly", "monthly", "interval" public DateTime? ScheduledDateTime { get; set; } // Per schedulazioni "once" [MaxLength(10)] public string? DailyTime { get; set; } // Format "HH:mm" per schedulazioni ricorrenti public int? DayOfWeek { get; set; } // 0-6 per schedulazioni settimanali (0=Domenica) public int? DayOfMonth { get; set; } // 1-31 per schedulazioni mensili // Configurazione per schedulazioni a intervalli public int? IntervalValue { get; set; } // Valore dell'intervallo (es. 5, 10, 30) [MaxLength(20)] public string? IntervalUnit { get; set; } // "seconds", "minutes", "hours", "days", "weeks", "months" // Tracking delle esecuzioni public DateTime? LastExecutionTime { get; set; } public DateTime? NextExecutionTime { get; set; } public int ExecutionCount { get; set; } = 0; [MaxLength(20)] public string LastExecutionStatus { get; set; } = string.Empty; // "success", "failed", "running" [MaxLength(1000)] public string? LastExecutionMessage { get; set; } public int? LastExecutionRecordCount { get; set; } // Configurazione override per database sources [MaxLength(100)] public string? SourceDatabaseOverride { get; set; } [MaxLength(100)] public string? DestinationDatabaseOverride { get; set; } // Metadati [MaxLength(100)] public string? CreatedBy { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? UpdatedAt { get; set; } public bool IsActive { get; set; } = true; // Metodi helper per calcolare la prossima esecuzione public DateTime? CalculateNextExecution() { if (!IsEnabled || !IsActive) return null; var now = DateTime.Now; return ScheduleType switch { "once" => ScheduledDateTime > now ? ScheduledDateTime : null, "daily" when !string.IsNullOrEmpty(DailyTime) => CalculateNextDaily(now), "weekly" when DayOfWeek.HasValue && !string.IsNullOrEmpty(DailyTime) => CalculateNextWeekly(now), "monthly" when DayOfMonth.HasValue && !string.IsNullOrEmpty(DailyTime) => CalculateNextMonthly(now), "interval" when IntervalValue.HasValue && !string.IsNullOrEmpty(IntervalUnit) => CalculateNextInterval(now), _ => null }; } public DateTime? CalculateNextExecutionFromLast() { if (!IsEnabled || !IsActive) return null; // Per intervalli, calcola dalla ultima esecuzione (o da ora se mai eseguito) if (ScheduleType == "interval" && IntervalValue.HasValue && !string.IsNullOrEmpty(IntervalUnit)) { var baseTime = LastExecutionTime ?? DateTime.Now; return CalculateNextInterval(baseTime); } // Per altri tipi, usa CalculateNextExecution normale return CalculateNextExecution(); } private DateTime CalculateNextDaily(DateTime now) { var time = TimeSpan.Parse(DailyTime!); var today = now.Date.Add(time); return today > now ? today : today.AddDays(1); } private DateTime CalculateNextWeekly(DateTime now) { var time = TimeSpan.Parse(DailyTime!); var targetDayOfWeek = (DayOfWeek)DayOfWeek!; var daysUntilTarget = ((int)targetDayOfWeek - (int)now.DayOfWeek + 7) % 7; if (daysUntilTarget == 0) { // È oggi, controlla se l'orario è già passato var todayAtTime = now.Date.Add(time); if (todayAtTime > now) return todayAtTime; else daysUntilTarget = 7; // Prossima settimana } return now.Date.AddDays(daysUntilTarget).Add(time); } private DateTime CalculateNextMonthly(DateTime now) { var time = TimeSpan.Parse(DailyTime!); var targetDay = DayOfMonth!.Value; var thisMonth = new DateTime(now.Year, now.Month, Math.Min(targetDay, DateTime.DaysInMonth(now.Year, now.Month))).Add(time); if (thisMonth > now) return thisMonth; // Prossimo mese var nextMonth = now.AddMonths(1); return new DateTime(nextMonth.Year, nextMonth.Month, Math.Min(targetDay, DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month))).Add(time); } private DateTime CalculateNextInterval(DateTime baseTime) { if (!IntervalValue.HasValue || string.IsNullOrEmpty(IntervalUnit)) return baseTime; return IntervalUnit.ToLower() switch { "seconds" => baseTime.AddSeconds(IntervalValue.Value), "minutes" => baseTime.AddMinutes(IntervalValue.Value), "hours" => baseTime.AddHours(IntervalValue.Value), "days" => baseTime.AddDays(IntervalValue.Value), "weeks" => baseTime.AddDays(IntervalValue.Value * 7), "months" => baseTime.AddMonths(IntervalValue.Value), _ => baseTime }; } /// /// Ottiene una descrizione leggibile della schedulazione /// public string GetScheduleDescription() { return ScheduleType switch { "once" => $"Una volta il {ScheduledDateTime:dd/MM/yyyy HH:mm}", "daily" => $"Ogni giorno alle {DailyTime}", "weekly" => $"Ogni {GetDayOfWeekName(DayOfWeek)} alle {DailyTime}", "monthly" => $"Il giorno {DayOfMonth} di ogni mese alle {DailyTime}", "interval" => GetIntervalDescription(), _ => "Non configurato" }; } private string GetIntervalDescription() { if (!IntervalValue.HasValue || string.IsNullOrEmpty(IntervalUnit)) return "Intervallo non configurato"; var unit = IntervalUnit.ToLower() switch { "seconds" => IntervalValue.Value == 1 ? "secondo" : "secondi", "minutes" => IntervalValue.Value == 1 ? "minuto" : "minuti", "hours" => IntervalValue.Value == 1 ? "ora" : "ore", "days" => IntervalValue.Value == 1 ? "giorno" : "giorni", "weeks" => IntervalValue.Value == 1 ? "settimana" : "settimane", "months" => IntervalValue.Value == 1 ? "mese" : "mesi", _ => IntervalUnit }; return $"Ogni {IntervalValue} {unit}"; } private string GetDayOfWeekName(int? dayOfWeek) { if (!dayOfWeek.HasValue) return "sconosciuto"; return ((DayOfWeek)dayOfWeek.Value).ToString() switch { "Monday" => "Lunedì", "Tuesday" => "Martedì", "Wednesday" => "Mercoledì", "Thursday" => "Giovedì", "Friday" => "Venerdì", "Saturday" => "Sabato", "Sunday" => "Domenica", _ => dayOfWeek.Value.ToString() }; } }