using Microsoft.Extensions.Logging; using ShellProgressBar; using System.Collections.ObjectModel; using View_by_Distance.Compare.Models; using View_by_Distance.Distance.Models.Stateless; using View_by_Distance.Face.Models.Stateless; using View_by_Distance.Metadata.Models; using View_by_Distance.People.Models.Stateless; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Compare; public partial class Compare : ICompare, IDisposable { private ProgressBar? _ProgressBar; private readonly ProgressBarOptions _ProgressBarOptions; public Compare(List args, ILogger? logger, AppSettings appSettings, bool isSilent, IConsole console) { if (isSilent) { } if (args is null) throw new NullReferenceException(nameof(args)); if (console is null) throw new NullReferenceException(nameof(console)); ICompare compare = this; long ticks = DateTime.Now.Ticks; _ProgressBarOptions = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; CompareWork(logger, appSettings, compare, ticks); } void ICompare.Tick() => _ProgressBar?.Tick(); void ICompare.ConstructProgressBar(int maxTicks, string message) { _ProgressBar?.Dispose(); _ProgressBar = new(maxTicks, message, _ProgressBarOptions); } void IDisposable.Dispose() { _ProgressBar?.Dispose(); GC.SuppressFinalize(this); } private static bool GetRunToDoCollectionFirst(AppSettings appSettings, long ticks) { bool result = appSettings.DistanceSettings.SaveSortingWithoutPerson; if (!result) result = !IId.IsOffsetDeterministicHashCode(appSettings.MetadataSettings); if (!result) { string[] directories; directories = Directory.GetDirectories(appSettings.ResultSettings.RootDirectory, "*", SearchOption.TopDirectoryOnly); if (directories.Length == 0) result = true; else { string seasonDirectory; DirectoryInfo directoryInfo; DateTime dateTime = new(ticks); string rootDirectory = appSettings.ResultSettings.RootDirectory; (int season, string seasonName) = IDate.GetSeason(dateTime.DayOfYear); string eDistanceContentDirectory = IResult.GetResultsDateGroupDirectory(appSettings.ResultSettings, nameof(E_Distance), appSettings.ResultSettings.ResultContent); FileSystemInfo fileSystemInfo = new DirectoryInfo(eDistanceContentDirectory); string[] checkDirectories = [ Path.Combine(rootDirectory, "Ancestry"), Path.Combine(rootDirectory, "Facebook"), Path.Combine(rootDirectory, "LinkedIn") ]; foreach (string checkDirectory in checkDirectories) { if (checkDirectory == rootDirectory) seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName}"); else seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName} {Path.GetFileName(checkDirectory)}"); if (!Directory.Exists(seasonDirectory)) _ = Directory.CreateDirectory(seasonDirectory); if (result) continue; directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) { directoryInfo = new(directory); if (directoryInfo.LastWriteTime > fileSystemInfo.LastWriteTime) { result = true; break; } } } } } if (result) result = true; if (!result) result = false; return result; } private static ReadOnlyCollections GetReadOnlyCollections(AppSettings appSettings) { ReadOnlyCollections result; ReadOnlyCollection personContainers = IPeople.GetPersonContainers(appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.PeopleSettings, appSettings.CompareSettings); ReadOnlyCollection personKeys = IPeople.GetPersonKeys(personContainers); result = IPeople.GetReadOnlyCollections(appSettings.ResultSettings, appSettings.PeopleSettings, appSettings.DistanceSettings, appSettings.CompareSettings, personContainers, personKeys); return result; } private static ReadOnlyCollection GetMappedExifDirectoryWithEncoding(AppSettings appSettings, ICompare compare, long ticks, ReadOnlyCollections readOnlyCollections) { ReadOnlyCollection results; ReadOnlyCollection exifDirectories = IDistance.GetMapped(appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.PeopleSettings, appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, readOnlyCollections); if (exifDirectories.Count == 0 && !appSettings.DistanceSettings.SaveSortingWithoutPerson) throw new NotSupportedException($"Switch {nameof(appSettings.DistanceSettings.SaveSortingWithoutPerson)}!"); results = IDistance.GetMappedExifDirectoryWithEncoding(compare, ticks, exifDirectories); if (results.Count == 0 && !appSettings.DistanceSettings.SaveSortingWithoutPerson) throw new NotSupportedException($"Switch {nameof(appSettings.DistanceSettings.SaveSortingWithoutPerson)}!"); return results; } private void CompareWork(ILogger? logger, AppSettings appSettings, ICompare compare, long ticks) { const int updated = 0; DistanceLimits? distanceLimits; logger?.LogInformation("{Ticks}", ticks); ReadOnlyCollection matrix; ReadOnlyCollection saveContainers; ReadOnlyCollection exifDirectories; ReadOnlyCollection preFiltered; ReadOnlyCollection postFiltered; ReadOnlyDictionary onlyOne; bool runToDoCollectionFirst = GetRunToDoCollectionFirst(appSettings, ticks); ReadOnlyCollections readOnlyCollections = GetReadOnlyCollections(appSettings); ReadOnlyCollection mappedExifDirectoryWithEncoding = GetMappedExifDirectoryWithEncoding(appSettings, compare, ticks, readOnlyCollections); ReadOnlyDictionary> keyValuePairs = IDistance.Extract(appSettings.CompareSettings, mappedExifDirectoryWithEncoding); foreach (string outputResolution in appSettings.CompareSettings.OutputResolutions) { if (runToDoCollectionFirst || outputResolution.Any(char.IsNumber)) continue; _ProgressBar?.Dispose(); logger?.LogInformation("{outputResolution}", outputResolution); exifDirectories = IFace.GetExifDirectories(appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, outputResolution); preFiltered = IDistance.GetPreFilterLocationContainer(appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, readOnlyCollections, keyValuePairs, exifDirectories); if (preFiltered.Count == 0) continue; distanceLimits = new(appSettings.DistanceSettings); postFiltered = IDistance.GetPostFilterLocationContainer(preFiltered, distanceLimits); if (postFiltered.Count == 0) continue; matrix = IDistance.GetMatrixLocationContainers(appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, mappedExifDirectoryWithEncoding, distanceLimits, postFiltered); if (matrix.Count == 0) continue; onlyOne = IDistance.GetOnlyOne(appSettings.DistanceSettings, matrix); if (onlyOne.Count == 0) continue; saveContainers = IDistance.GetSaveContainers(appSettings.ResultSettings, appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, outputResolution, onlyOne); if (saveContainers.Count == 0) continue; IDistance.SaveContainers(appSettings.DistanceSettings, appSettings.CompareSettings, compare, ticks, updated, saveContainers); } } }