using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using JobEngineDAL.DTOs; using JobEngineDAL.Interfaces; using JobEngineBLL.Interfaces; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace JobEngineBLL.Implementations { public class SchedulerBLL : ISchedulerBLL { private readonly ISchedulerDAL _dal; private readonly ILogger _logger; public SchedulerBLL(ISchedulerDAL dal, ILogger logger) { _dal = dal; _logger = logger; } public async Task GetSchedulersAsync(LoginDTO login, CancellationToken ct) { try { var schedulers = await _dal.GetSchedulersAsync(login, ct).ConfigureAwait(false); return JsonConvert.SerializeObject(schedulers); } catch (Exception ex) { GB5Trace.MarkFailed("get-schedulers-failed", ex); _logger.LogError(ex, "GetSchedulers failed"); throw; } } public async Task SaveSchedulerAsync(SchedulerDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-scheduler", new { dto.SchedulerId }); if (string.IsNullOrWhiteSpace(dto.SchedulerType)) throw new ArgumentException("SchedulerType is required"); switch (dto.SchedulerType) { case "CRON" when string.IsNullOrWhiteSpace(dto.CronExpression): throw new ArgumentException("CronExpression is required for CRON schedulers"); case "INTERVAL" when (dto.IntervalSeconds ?? 0) <= 0: throw new ArgumentException("IntervalSeconds must be positive for INTERVAL schedulers"); case "ONE_TIME" when dto.ScheduledDate == null: throw new ArgumentException("ScheduledDate is required for ONE_TIME schedulers"); } bool isNew = dto.SchedulerId == 0; GB5Trace.Step("save-scheduler", new { dto.SchedulerId, isNew }); var savedId = await _dal.SaveSchedulerAsync(dto, login, ct).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-scheduler-failed", ex); _logger.LogError(ex, "SaveScheduler failed for SchedulerId {Id}", dto.SchedulerId); throw; } } } }