using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Cleanuparr.Api.Features.MalwareBlocker.Contracts.Requests; using Cleanuparr.Infrastructure.Models; using Cleanuparr.Infrastructure.Services.Interfaces; using Cleanuparr.Infrastructure.Utilities; using Cleanuparr.Persistence; using Cleanuparr.Persistence.Models.Configuration; using Cleanuparr.Persistence.Models.Configuration.MalwareBlocker; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace Cleanuparr.Api.Features.MalwareBlocker.Controllers; [ApiController] [Route("api/configuration")] public sealed class MalwareBlockerConfigController : ControllerBase { private readonly ILogger _logger; private readonly DataContext _dataContext; private readonly IJobManagementService _jobManagementService; public MalwareBlockerConfigController( ILogger logger, DataContext dataContext, IJobManagementService jobManagementService) { _logger = logger; _dataContext = dataContext; _jobManagementService = jobManagementService; } [HttpGet("malware_blocker")] public async Task GetMalwareBlockerConfig() { await DataContext.Lock.WaitAsync(); try { var config = await _dataContext.ContentBlockerConfigs .AsNoTracking() .FirstAsync(); return Ok(config); } finally { DataContext.Lock.Release(); } } [HttpPut("malware_blocker")] public async Task UpdateMalwareBlockerConfig([FromBody] UpdateMalwareBlockerConfigRequest request) { await DataContext.Lock.WaitAsync(); try { if (!string.IsNullOrEmpty(request.CronExpression)) { CronValidationHelper.ValidateCronExpression(request.CronExpression, JobType.MalwareBlocker); } var config = await _dataContext.ContentBlockerConfigs .FirstAsync(); request.ApplyTo(config); config.Validate(); await _dataContext.SaveChangesAsync(); await UpdateJobSchedule(config, JobType.MalwareBlocker); return Ok(new { Message = "MalwareBlocker configuration updated successfully" }); } catch (ValidationException ex) { return BadRequest(ex.Message); } catch (Exception ex) { _logger.LogError(ex, "Failed to save MalwareBlocker configuration"); throw; } finally { DataContext.Lock.Release(); } } private async Task UpdateJobSchedule(IJobConfig config, JobType jobType) { if (config.Enabled) { if (!string.IsNullOrEmpty(config.CronExpression)) { _logger.LogInformation("{name} is enabled, updating job schedule with cron expression: {CronExpression}", jobType.ToString(), config.CronExpression); await _jobManagementService.StartJob(jobType, null, config.CronExpression); } else { _logger.LogWarning("{name} is enabled, but no cron expression was found in the configuration", jobType.ToString()); } return; } _logger.LogInformation("{name} is disabled, stopping the job", jobType.ToString()); await _jobManagementService.StopJob(jobType); } }