namespace Harmonia.Core.Data; public abstract class FileRepository : IRepository where TObject : notnull { private readonly Dictionary _fileNameMap = []; protected abstract string DirectoryName { get; } protected abstract string Extension { get; } protected abstract string GetNewFileName(); protected abstract Task SerializeAsync(TObject playlist); protected abstract Task DeserializeAsync(Stream stream); public async Task InitializeAsync() { if (string.IsNullOrWhiteSpace(DirectoryName)) return; if (Directory.Exists(DirectoryName) == false) Directory.CreateDirectory(DirectoryName); if (string.IsNullOrWhiteSpace(Extension)) return; List fileNames = GetAllFileNames(); await LoadFileNamesIntoMapAsync(fileNames); } private List GetAllFileNames() { var directoryInfo = new DirectoryInfo(DirectoryName); var directories = directoryInfo.GetDirectories().Where(x => x.Attributes.HasFlag(FileAttributes.Hidden) == false); var fileInfoList = directoryInfo.EnumerateFiles("*." + Extension, SearchOption.TopDirectoryOnly).Where(x => x.Attributes.HasFlag(FileAttributes.Hidden) == false); return [.. fileInfoList.Select(fileInfo => fileInfo.FullName)]; } private async Task LoadFileNamesIntoMapAsync(List fileNames) { foreach (var fileName in fileNames) { using StreamReader textReader = new(fileName); try { TObject obj = await DeserializeAsync(textReader.BaseStream); _fileNameMap.Add(obj, fileName); } catch (Exception) { } } } public List Get() { return [.. _fileNameMap.Keys]; } public async Task SaveAsync(TObject obj) { string serializedObject = await SerializeAsync(obj); string fileName = Path.Combine(DirectoryName, GetFileName(obj)); string? path = Path.GetDirectoryName(fileName); if (string.IsNullOrWhiteSpace(path)) return; if (Directory.Exists(path) == false) Directory.CreateDirectory(path); //using TextWriter textWriter = new StreamWriter(fileName); //await textWriter.WriteAsync(serializedObject); await File.WriteAllTextAsync(fileName, serializedObject); } private string GetFileName(TObject obj) { if (_fileNameMap.TryGetValue(obj, out string? value)) return value; string fileName = GetNewFileName(); _fileNameMap.Add(obj, fileName); return fileName; } public void Delete(TObject obj) { string fileName = Path.Combine(DirectoryName, GetFileName(obj)); _fileNameMap.Remove(obj); if (File.Exists(fileName)) File.Delete(fileName); } }