namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class PersonContainer { private static string[] GetFiles(string facesFileNameExtension, string personDisplayDirectory) { string[] results = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly); int? id; string checkFile; string? checkDirectory; int? normalizedPixelPercentage; foreach (string personDisplayDirectoryAllFile in results) { if (personDisplayDirectoryAllFile.EndsWith(".lnk")) continue; (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, personDisplayDirectoryAllFile); if (id is not null && normalizedPixelPercentage is not null && !personDisplayDirectoryAllFile.EndsWith(".json")) continue; checkDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile); if (string.IsNullOrEmpty(checkDirectory)) continue; checkDirectory = Path.Combine(checkDirectory, "_ Invalid"); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); checkFile = Path.Combine(checkDirectory, Path.GetFileName(personDisplayDirectoryAllFile)); if (File.Exists(checkFile)) File.Delete(personDisplayDirectoryAllFile); else File.Move(personDisplayDirectoryAllFile, checkFile); } results = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.AllDirectories); return results; } private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, Models.PersonBirthday[] personBirthdays) { List<(long?, Models.PersonContainer)> results = new(); long personKey; string[] segments; const int zero = 0; Models.Person person; string personKeyFormatted; Models.PersonBirthday? personBirthday; Models.PersonContainer personContainer; string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory); foreach (string personKeyDirectory in personKeyDirectories) { personKeyFormatted = Path.GetFileName(personKeyDirectory); personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted); if (personBirthday is null) continue; if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#')))) throw new NotSupportedException(); personKey = personBirthdays[zero].Value.Ticks; if (personKey != personBirthdays.OrderByDescending(l => l.Value.Ticks).ToArray()[0].Value.Ticks) throw new NotSupportedException(); segments = personDisplayDirectoryName.Split(chars); person = IPerson.GetPerson(personKey, segments); personContainer = new(approximateYears, person, personBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey); results.Add(new(personKey, personContainer)); } return results; } private static Models.PersonContainer GetPersonContainer(string facesFileNameExtension, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears) { Models.PersonContainer result; string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory); result = new(approximateYears, personDisplayDirectoryAllFiles, personDisplayDirectoryName); return result; } private static string? VerifyAge(string personDisplayDirectory, string minusOne, string personDisplayDirectoryName, int? approximateYears, Models.PersonBirthday[] personBirthdays) { string? result; if (approximateYears is null) throw new NotSupportedException(); if (!personBirthdays.Any()) throw new NotSupportedException(); const int zero = 0; int? updateApproximateYears; DateTime dateTime = DateTime.Now; TimeSpan timeSpan = new(personBirthdays[zero].Value.Ticks - dateTime.AddYears(-approximateYears.Value).Ticks); if (timeSpan.TotalDays < -356) updateApproximateYears = approximateYears.Value + 1; else if (timeSpan.TotalDays > 356) updateApproximateYears = approximateYears.Value - 1; else updateApproximateYears = null; if (updateApproximateYears is null) result = null; else { result = Path.Combine(minusOne, $"{personDisplayDirectoryName.Split('^')[0]}^{updateApproximateYears}"); if (Directory.Exists(result)) result = null; else Directory.Move(personDisplayDirectory, result); } return result; } private static List<(long?, Models.PersonContainer)> GetPersonContainersGroup(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] personDisplayDirectories) { List<(long?, Models.PersonContainer)> results = new(); string? minusOne; int? approximateYears; List changes = new(); string[] personKeyDirectories; string? personDisplayDirectoryName; Models.PersonContainer personContainer; Models.PersonBirthday[] personBirthdays; foreach (string personDisplayDirectory in personDisplayDirectories) { personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory); if (string.IsNullOrEmpty(personDisplayDirectoryName)) continue; approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars); personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly); personBirthdays = PersonBirthday.GetDescendingOrderedPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory); if (personDisplayDirectoryName.Contains('^')) { minusOne = Path.GetDirectoryName(personDisplayDirectory); if (minusOne is null) continue; changes.Add(VerifyAge(personDisplayDirectory, minusOne, personDisplayDirectoryName, approximateYears, personBirthdays)); } if (changes.Any(l => l is not null)) continue; if (personBirthdays.Any()) results.AddRange(GetPersonContainersCollections(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, personBirthdays)); else { personContainer = GetPersonContainer(facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears); results.Add(new(null, personContainer)); } } if (changes.Any(l => l is not null)) throw new NotImplementedException($"A directory was changed restart to look for more! {string.Join(Environment.NewLine, (from l in changes where l is not null select l).ToArray())}"); return results; } private static Models.PersonContainer[] GetPersonContainersGroups(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] groupDirectories) { Models.PersonContainer[] results; const int zero = 0; string groupDirectoryName; string[] personDisplayDirectories; List<(long?, Models.PersonContainer)> collection; List<(long? PersonKey, Models.PersonContainer PersonContainer)> personContainers = new(); foreach (string groupDirectory in groupDirectories) { groupDirectoryName = Path.GetFileName(groupDirectory); if (!chars.Contains(groupDirectoryName[zero])) continue; personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly); collection = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectories); personContainers.AddRange(collection); } results = (from l in personContainers orderby l.PersonKey is not null, l.PersonKey select l.PersonContainer).ToArray(); return results; } internal static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat, string facesFileNameExtension) { Models.PersonContainer[] results; char[] chars = IAge.GetChars(); string a2PeopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}"); if (!Directory.Exists(a2PeopleSingletonDirectory)) _ = Directory.CreateDirectory(a2PeopleSingletonDirectory); string a2PeopleSingletonDirectoryChar; foreach (char @char in chars) { a2PeopleSingletonDirectoryChar = Path.Combine(a2PeopleSingletonDirectory, @char.ToString()); if (!Directory.Exists(a2PeopleSingletonDirectoryChar)) _ = Directory.CreateDirectory(a2PeopleSingletonDirectoryChar); } string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly); if (!groupDirectories.Any()) results = Array.Empty(); else results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, chars, groupDirectories); return results; } internal static List<(long?, string)> GetDisplay(string personBirthdayFormat, Models.PersonContainer personContainer) { List<(long?, string)> results = new(); string personKeyFormatted; Models.PersonContainer pc = personContainer; if (pc.Person is null || pc.Key is null || pc.Birthdays is null || !pc.Birthdays.Any()) results.Add(new(pc.Key, string.Concat('\t', pc.Key, '\t', pc.ApproximateYears, '\t', pc.DisplayDirectoryName))); else { foreach (Models.PersonBirthday personBirthday in pc.Birthdays) { personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday); results.Add(new(pc.Key, string.Concat(personKeyFormatted, '\t', pc.Key, '\t', pc.ApproximateYears, '\t', pc.DisplayDirectoryName))); } } return results; } }