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 string Serialize(TObject playlist); protected abstract TObject Deserialize(Stream stream); public FileRepository() { if (string.IsNullOrWhiteSpace(DirectoryName)) return; if (Directory.Exists(DirectoryName) == false) Directory.CreateDirectory(DirectoryName); if (string.IsNullOrWhiteSpace(Extension)) return; List fileNames = GetAllFileNames(); LoadFileNamesIntoMap(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 void LoadFileNamesIntoMap(List fileNames) { foreach (var fileName in fileNames) { using StreamReader textReader = new(fileName); try { TObject obj = Deserialize(textReader.BaseStream); _fileNameMap.Add(obj, fileName); } catch (Exception) { } } } public List Get() { return [.. _fileNameMap.Keys]; } public void Save(TObject obj) { string serializedObject = Serialize(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); textWriter.Write(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)); if (File.Exists(fileName)) File.Delete(fileName); } }