using System.Collections.ObjectModel; using View_by_Distance.Metadata.Models; using View_by_Distance.Metadata.Models.Stateless; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Properties; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Distance.Models.Stateless; internal static class MappedLogicA { internal record MappedFile(PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, string? PersonDisplayDirectoryName, FilePath FilePath); private static List GetDisplayDirectoryAllFiles(PeopleSettings peopleSettings, ICompareSettings compareSettings, ReadOnlyCollections readOnlyCollections) { List results = []; FilePath filePath; MappedFile mappedFile; string personKeyFormatted; List distinct = []; PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName personKeyFormattedAndKeyTicksAndDisplayDirectoryName; foreach (PersonContainer personContainer in readOnlyCollections.PersonContainers) { if (personContainer.Key is null) continue; for (int i = personContainer.DisplayDirectoryAllFilePaths.Count - 1; i > -1; i--) { filePath = personContainer.DisplayDirectoryAllFilePaths[i]; if (filePath.ExtensionLowered != compareSettings.FacesFileNameExtension) continue; if (distinct.Contains(filePath.Name)) continue; distinct.Add(filePath.Name); personKeyFormatted = IPersonBirthday.GetFormatted(peopleSettings.PersonBirthdayFormat, personContainer.Key.Value); personKeyFormattedAndKeyTicksAndDisplayDirectoryName = new(personKeyFormatted, personContainer.Key.Value, filePath.Name); mappedFile = new(personKeyFormattedAndKeyTicksAndDisplayDirectoryName, personContainer.DisplayDirectoryName, filePath); results.Add(mappedFile); } } return results; } private static ReadOnlyCollection GetMappedFiles(ResultSettings resultSettings, MetadataSettings metadataSettings, PeopleSettings peopleSettings, ICompareSettings compareSettings, ReadOnlyCollections readOnlyCollections, ReadOnlyCollection records) { List results = []; long personKey; string checkFile; FilePath filePath; FileHolder fileHolder; MappedFile mappedFile; List distinct = []; PersonBirthday? personBirthday; PersonContainer? personContainer; string? personDisplayDirectoryName; results.AddRange(GetDisplayDirectoryAllFiles(peopleSettings, compareSettings, readOnlyCollections)); PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName personKeyFormattedAndKeyTicksAndDisplayDirectoryName; ReadOnlyDictionary keyValuePairs = PersonContainer.Extract(readOnlyCollections.PersonContainers); foreach (MappedLogicB.Record record in records) { personBirthday = IPersonBirthday.GetPersonBirthday(peopleSettings.PersonBirthdayFormat, record.PersonKeyFormatted); if (personBirthday is null) continue; if (distinct.Contains(record.MappedFaceFilePath.Name)) continue; personKey = personBirthday.Value.Ticks; distinct.Add(record.MappedFaceFilePath.Name); if (!keyValuePairs.TryGetValue(personKey, out personContainer)) personDisplayDirectoryName = record.PersonDisplayDirectoryName; else personDisplayDirectoryName = personContainer.DisplayDirectoryName; personKeyFormattedAndKeyTicksAndDisplayDirectoryName = new(record.PersonKeyFormatted, personKey, personDisplayDirectoryName); mappedFile = new(personKeyFormattedAndKeyTicksAndDisplayDirectoryName, personDisplayDirectoryName, record.MappedFaceFilePath); results.Add(mappedFile); } for (int i = results.Count - 1; i > -1; i--) { filePath = results[i].FilePath; if (filePath.Name.EndsWith(".old")) { results.RemoveAt(i); continue; } if (!filePath.Name.EndsWith(".abd") && !filePath.Name.EndsWith(".brt") && !filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk")) continue; checkFile = filePath.FullName[..^4]; if (File.Exists(checkFile)) continue; File.Move(filePath.FullName, checkFile); fileHolder = FileHolder.Get(checkFile); filePath = FilePath.Get(resultSettings, metadataSettings, fileHolder, index: null); results[i] = new(results[i].PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, results[i].PersonDisplayDirectoryName, filePath); } for (int i = results.Count - 1; i > -1; i--) { if (File.Exists(results[i].FilePath.FullName)) continue; results.RemoveAt(i); } return results.AsReadOnly(); } private static void MappedParallelFor(ResultSettings resultSettings, MetadataSettings metadataSettings, DistanceSettings distanceSettings, ICompareSettings compareSettings, List exifDirectories, ReadOnlyDictionary> skipCollection, MappedFile mappedFile) { int? id; int? wholePercentages; const string lnk = ".lnk"; if (!mappedFile.FilePath.Name.EndsWith(lnk)) { if (mappedFile.FilePath.Id is null) return; id = mappedFile.FilePath.Id; wholePercentages = IMapping.GetWholePercentages(compareSettings, mappedFile.FilePath); } else { FileHolder fileHolder = FileHolder.Get(mappedFile.FilePath.FullName[..^4]); FilePath filePath = FilePath.Get(resultSettings, metadataSettings, fileHolder, index: null); if (filePath.Id is null) return; id = filePath.Id; wholePercentages = IMapping.GetWholePercentages(compareSettings, filePath); } if (wholePercentages is null) return; if (distanceSettings.LinkedAlpha is null && string.IsNullOrEmpty(distanceSettings.LocationContainerDebugDirectory)) { if (skipCollection.TryGetValue(id.Value, out List? wholePercentagesCollection)) { string checkFile; FilePath[] filePathMatches = (from l in wholePercentagesCollection where l.WholePercentages == wholePercentages select l.FilePath).ToArray(); foreach (FilePath filePathMatch in filePathMatches) { if (string.IsNullOrEmpty(filePathMatch.FullName) || !File.Exists(filePathMatch.FullName)) continue; checkFile = $"{filePathMatch}.dup"; if (File.Exists(checkFile)) continue; File.Move(filePathMatch.FullName, checkFile); continue; } } } if (mappedFile.FilePath.Name.EndsWith(lnk) || !File.Exists(mappedFile.FilePath.FullName)) return; Stream stream = File.OpenRead(mappedFile.FilePath.FullName); ExifDirectory exifDirectory = IMetadata.GetExifDirectory(mappedFile.FilePath, stream, mappedFile.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName); stream.Dispose(); lock (exifDirectories) exifDirectories.Add(exifDirectory); } internal static ReadOnlyCollection GetMapped(ResultSettings resultSettings, MetadataSettings metadataSettings, PeopleSettings peopleSettings, DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, long ticks, ReadOnlyCollections readOnlyCollections) { List results = []; string eDistanceContentDirectory = IResult.GetResultsDateGroupDirectory(resultSettings, nameof(E_Distance), resultSettings.ResultContent); ReadOnlyCollection records = MappedLogicB.DeleteEmptyDirectoriesAndGetCollection(resultSettings, metadataSettings, peopleSettings, distanceSettings, compareSettings, compare, ticks, eDistanceContentDirectory, readOnlyCollections); ReadOnlyCollection mappedFiles = GetMappedFiles(resultSettings, metadataSettings, peopleSettings, compareSettings, readOnlyCollections, records); if (mappedFiles.Count > 0) { int maxDegreeOfParallelism = compareSettings.MaxDegreeOfParallelism; int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)"; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ReadOnlyDictionary> skipNotSkipCollection = readOnlyCollections.SkipNotSkipCollection; compare.ConstructProgressBar(mappedFiles.Count, message); _ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) => { compare.Tick(); MappedParallelFor(resultSettings, metadataSettings, distanceSettings, compareSettings, results, skipNotSkipCollection, mappedFiles[i]); }); } return results.AsReadOnly(); } internal static ReadOnlyDictionary> Extract(ICompareSettings compareSettings, ReadOnlyCollection exifDirectories) { Dictionary> results = []; int? wholePercentages; Dictionary? keyValues; Dictionary> keyValuePairs = []; foreach (ExifDirectory exifDirectory in exifDirectories) { if (exifDirectory.FilePath.Id is null) continue; if (!keyValuePairs.TryGetValue(exifDirectory.FilePath.Id.Value, out keyValues)) { keyValuePairs.Add(exifDirectory.FilePath.Id.Value, []); if (!keyValuePairs.TryGetValue(exifDirectory.FilePath.Id.Value, out keyValues)) throw new Exception(); } wholePercentages = IMapping.GetWholePercentages(compareSettings, exifDirectory.FilePath); if (wholePercentages is null) continue; keyValues.Add(wholePercentages.Value, exifDirectory.FilePath); } foreach (KeyValuePair> keyValuePair in keyValuePairs) results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly()); return results.AsReadOnly(); } }