using System.Text; using System.Text.Json; using SharepointToolbox.Web.Core.Models; namespace SharepointToolbox.Web.Infrastructure.Persistence; public class TemplateRepository { private readonly string _directory; private readonly SemaphoreSlim _lock = new(1, 1); public TemplateRepository(string directory) { _directory = directory; } public async Task> GetAllAsync() { if (!Directory.Exists(_directory)) return Array.Empty(); var files = Directory.GetFiles(_directory, "*.json"); var templates = new List(); foreach (var file in files) { try { var json = await File.ReadAllTextAsync(file, Encoding.UTF8); var t = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (t is not null) templates.Add(t); } catch { /* skip corrupt files */ } } return templates.OrderByDescending(t => t.CapturedAt).ToList(); } public async Task GetByIdAsync(string id) { var file = Path.Combine(_directory, $"{id}.json"); if (!File.Exists(file)) return null; try { var json = await File.ReadAllTextAsync(file, Encoding.UTF8); return JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } catch { return null; } } public async Task SaveAsync(SiteTemplate template) { await _lock.WaitAsync(); try { Directory.CreateDirectory(_directory); var json = JsonSerializer.Serialize(template, new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var path = Path.Combine(_directory, $"{template.Id}.json"); var tmp = path + ".tmp"; await File.WriteAllTextAsync(tmp, json, Encoding.UTF8); File.Move(tmp, path, overwrite: true); } finally { _lock.Release(); } } public Task DeleteAsync(string id) { var file = Path.Combine(_directory, $"{id}.json"); if (File.Exists(file)) File.Delete(file); return Task.CompletedTask; } public async Task RenameAsync(string id, string newName) { var t = await GetByIdAsync(id); if (t is null) return; t.Name = newName; await SaveAsync(t); } }