using System.Collections.ObjectModel; using View_by_Distance.Shared.Models.Properties; namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class FilePair { internal static ReadOnlyCollection GetFilePairs(IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string jsonGroupDirectory, ReadOnlyCollection> filePathsCollection) { ReadOnlyCollection results; ReadOnlyDictionary> fileNamesToFiles = FilePath.GetFilesKeyValuePairs(filePathsCollection); results = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, jsonGroupDirectory, filePathsCollection, fileNamesToFiles); return results; } internal static ReadOnlyCollection GetFilePairs(IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string jsonGroupDirectory, ReadOnlyCollection> filePathsCollection, ReadOnlyDictionary> fileNamesToFiles) { List? results = null; int renamed; const bool useCeilingAverage = true; ReadOnlyCollection? jsonFilesCollection = null; IReadOnlyDictionary>? compareFileNamesToFiles = null; for (int i = 0; i < fileNamesToFiles.Count; i++) { renamed = 0; jsonFilesCollection = XDirectory.GetFilesCollection(jsonGroupDirectory, directorySearchFilter, extension, useCeilingAverage); renamed += LookForAbandoned(propertyConfiguration, jsonFilesCollection, fileNamesToFiles, extension); if (renamed > 0) continue; compareFileNamesToFiles = GetKeyValuePairs(propertyConfiguration, jsonFilesCollection); results = XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, compareFileNamesToFiles); renamed += XDirectory.MaybeMove(propertyConfiguration, results, jsonGroupDirectory, extension); if (renamed == 0) break; if (i > 10) throw new NotImplementedException(); } if (results is null || jsonFilesCollection is null || compareFileNamesToFiles is null) throw new NullReferenceException(nameof(results)); return results.AsReadOnly(); } private static int LookForAbandoned(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection jsonFilesCollection, IReadOnlyDictionary> fileNamesToFiles, string extension) { int result; bool check; bool moved = false; List renameCollection = []; foreach (string[] files in jsonFilesCollection) { if (files.Length == 0) continue; check = AnyMoved(propertyConfiguration, fileNamesToFiles, extension, renameCollection, files); if (!moved && check) moved = true; } if (renameCollection.Count > 0) XDirectory.MoveFiles(renameCollection, "{}", "{abd}"); result = renameCollection.Count; if (moved && result == 0) result = 1; return result; } private static bool AnyMoved(IPropertyConfiguration propertyConfiguration, IReadOnlyDictionary> fileNamesToFiles, string extension, List renameCollection, string[] files) { bool result = false; string checkFile; string directory; FilePath filePath; string fileNameWith; string checkDirectory; string directoryName; List? collection; Models.FileHolder fileHolder; List directoryNames = []; foreach (string file in files) { if (!file.EndsWith(extension)) throw new Exception(); fileHolder = IFileHolder.Get(file); if (!fileHolder.Exists) continue; filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null); if (filePath.Id is null) continue; if (!fileNamesToFiles.TryGetValue(filePath.Id.Value, out collection)) renameCollection.Add(file); else { directoryNames.Clear(); directoryName = Path.GetFileName(filePath.DirectoryFullPath) ?? throw new Exception(); foreach (FilePath f in collection) directoryNames.Add(Path.GetFileName(f.DirectoryFullPath) ?? throw new Exception()); if (directoryNames.Count == 0 || directoryNames.Distinct().Count() != 1) continue; if (directoryName != directoryNames[0]) { directory = Path.GetDirectoryName(filePath.DirectoryFullPath) ?? throw new Exception(); checkDirectory = Path.Combine(directory, directoryNames[0]); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); fileNameWith = collection.Count > 1 ? filePath.Name : $"{collection[0].Name}{extension}"; checkFile = Path.Combine(checkDirectory, fileNameWith); if (!result) result = true; if (!File.Exists(checkFile)) File.Move(file, checkFile); else { if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime) File.Delete(file); else File.Move(file, checkFile, true); } } } } return result; } private static ReadOnlyDictionary> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection) { Dictionary> results = []; List? collection; FilePath filePath; Models.FileHolder fileHolder; foreach (string[] files in filesCollection) { foreach (string file in files) { fileHolder = IFileHolder.Get(file); if (!fileHolder.Exists) continue; filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null); if (filePath.Id is null) continue; if (!results.TryGetValue(filePath.Id.Value, out collection)) { results.Add(filePath.Id.Value, []); if (!results.TryGetValue(filePath.Id.Value, out collection)) throw new Exception(); } collection.Add(filePath); } } return new(results); } }