using System.Text.Json; using WebApp.Models; namespace WebApp.Services; /// /// Persists chapter settings to Data/appsettings.json. /// public class ChapterSettingsWriter : IChapterSettingsWriter { private readonly IWebHostEnvironment _environment; private readonly IConfiguration _configuration; private readonly ILogger _logger; public ChapterSettingsWriter( IWebHostEnvironment environment, IConfiguration configuration, ILogger logger) { _environment = environment; _configuration = configuration; _logger = logger; } public async Task WriteAsync(ChapterSettings settings, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(settings); var appSettingsPath = GetAppSettingsPath(); var dataDir = Path.GetDirectoryName(appSettingsPath); if (dataDir != null && !Directory.Exists(dataDir)) { Directory.CreateDirectory(dataDir); } Dictionary root; if (File.Exists(appSettingsPath)) { var existingJson = await File.ReadAllTextAsync(appSettingsPath, cancellationToken); root = JsonSerializer.Deserialize>(existingJson) ?? []; } else { root = []; } root["ChapterSettings"] = settings; var options = new JsonSerializerOptions { WriteIndented = true }; var json = JsonSerializer.Serialize(root, options); await File.WriteAllTextAsync(appSettingsPath, json, cancellationToken); _logger.LogInformation("Chapter settings written to {Path}", appSettingsPath); } public async Task UpdateCompetitionYearAsync(string competitionYear, CancellationToken cancellationToken = default) { var settings = _configuration.GetSection("ChapterSettings").Get() ?? new ChapterSettings(); settings.CompetitionYear = competitionYear; await WriteAsync(settings, cancellationToken); } private string GetAppSettingsPath() => Path.Combine(_environment.ContentRootPath, "Data", "appsettings.json"); }