using System.Collections.ObjectModel; using View_by_Distance.Shared.Models.Properties; namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class XPath { private static ReadOnlyDictionary> Convert(List collection) { Dictionary> results = []; List? c; foreach (CombinedEnumAndIndex cei in collection) { if (!results.TryGetValue(cei.Enum, out c)) { results.Add(cei.Enum, []); if (!results.TryGetValue(cei.Enum, out c)) throw new Exception(); } c.Add(cei.Combined); } return Convert(results); } internal static void DeleteEmptyDirectories(string rootDirectory, List deletedDirectories) { if (Directory.Exists(rootDirectory)) { string[] files; string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly); if (directories.Length > 0) files = []; else files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories); if (directories.Length == 0 && files.Length == 0) { deletedDirectories.Add(rootDirectory); try { Directory.Delete(rootDirectory); } catch (UnauthorizedAccessException) { new DirectoryInfo(rootDirectory).Attributes = FileAttributes.Normal; Directory.Delete(rootDirectory); } } else { List check = []; foreach (string directory in directories) { DeleteEmptyDirectories(directory, check); deletedDirectories.AddRange(check); if (check.Count > 0) DeleteEmptyDirectories(directory, deletedDirectories); } } } } internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath, string fileNameWithoutExtension) { CombinedEnumAndIndex result; byte @enum; int converted; string combined; byte missingDateTimeOriginal = IId.GetMissingDateTimeOriginal(propertyConfiguration, filePath); if (!filePath.IsIntelligentIdFormat) @enum = missingDateTimeOriginal; else { if (filePath.HasIgnoreKeyword is null || filePath.HasDateTimeOriginal is null) throw new NotImplementedException("Chicken and Egg!"); if (filePath.HasIgnoreKeyword.Value) @enum = IId.GetHasIgnoreKeyword(filePath); else if (!filePath.HasDateTimeOriginal.Value) @enum = missingDateTimeOriginal; else @enum = IId.GetHasDateTimeOriginal(propertyConfiguration, filePath); } string fileNameBeforeFirst = fileNameWithoutExtension.Split('.')[0]; string check = fileNameBeforeFirst.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength ? new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength) : fileNameBeforeFirst[^propertyConfiguration.ResultAllInOneSubdirectoryLength..]; if (check.Any(l => !char.IsNumber(l))) { combined = $"{@enum}{new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)}"; converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}"); } else { combined = $"{@enum}{check}"; converted = int.Parse(check); } result = new(combined, @enum, converted); return result; } internal static byte GetEnum(FilePath filePath) => GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal); private static byte GetEnum(bool? ik, bool? dto) { byte result; if (ik is not null && ik.Value && dto is not null && dto.Value) result = 11; else if (ik is not null && ik.Value && dto is not null && !dto.Value) result = 15; else if (ik is not null && ik.Value && dto is null) result = 19; else if (ik is not null && !ik.Value && dto is not null && dto.Value) result = 51; else if (ik is not null && !ik.Value && dto is not null && !dto.Value) result = 55; else if (ik is not null && !ik.Value && dto is null) result = 59; else if (ik is null && dto is not null && dto.Value) result = 91; else if (ik is null && dto is not null && !dto.Value) result = 95; else if (ik is null && dto is null) result = 99; else throw new Exception(); return result; } internal static List GetDirectories(string directory) { List results = []; string? checkDirectory = directory; string? pathRoot = Path.GetPathRoot(directory); if (string.IsNullOrEmpty(pathRoot)) throw new NullReferenceException(nameof(pathRoot)); if (Directory.Exists(directory)) results.Add(directory); for (int i = 0; i < int.MaxValue; i++) { checkDirectory = Path.GetDirectoryName(checkDirectory); if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) break; results.Add(checkDirectory); } results.Add(pathRoot); results.Reverse(); return results; } internal static List GetDirectoryNames(string directory) { List results = []; string? fileName; string? checkDirectory = directory; string? pathRoot = Path.GetPathRoot(directory); string extension = Path.GetExtension(directory); if (string.IsNullOrEmpty(pathRoot)) throw new NullReferenceException(nameof(pathRoot)); if (Directory.Exists(directory)) { fileName = Path.GetFileName(directory); if (!string.IsNullOrEmpty(fileName)) results.Add(fileName); } else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory)) { fileName = Path.GetFileName(directory); if (!string.IsNullOrEmpty(fileName)) results.Add(fileName); } for (int i = 0; i < int.MaxValue; i++) { checkDirectory = Path.GetDirectoryName(checkDirectory); if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot) break; fileName = Path.GetFileName(checkDirectory); if (string.IsNullOrEmpty(fileName)) continue; results.Add(fileName); } results.Add(pathRoot); results.Reverse(); return results; } internal static bool DeleteEmptyDirectories(string rootDirectory) { bool result; List results = []; DeleteEmptyDirectories(rootDirectory, results); result = results.Count > 0; return result; } internal static void MakeHiddenIfAllItemsAreHidden(string rootDirectory) { bool check; FileInfo fileInfo; IEnumerable files; DirectoryInfo directoryInfo; IEnumerable subDirectories; string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories); foreach (string directory in directories) { directoryInfo = new(directory); if (directoryInfo.Attributes.HasFlag(FileAttributes.Hidden)) continue; check = true; subDirectories = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly); foreach (string subDirectory in subDirectories) { directoryInfo = new(subDirectory); if (!directoryInfo.Attributes.HasFlag(FileAttributes.Hidden)) { check = false; break; } } if (!check) continue; files = Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) { fileInfo = new(file); if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) { check = false; break; } } if (!check) continue; directoryInfo.Attributes |= FileAttributes.Hidden; } } internal static void CreateDirectories(ReadOnlyCollection directories) { string checkDirectory; foreach (string directory in directories) { for (int i = 0; i < 101; i++) { checkDirectory = Path.Combine(directory, i.ToString("000")); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); } } } internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks) { DateTime dateTime = new(ticks); IEnumerable fileSystemEntries; string[] directories; if (!Directory.Exists(rootDirectory)) directories = []; else directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories); foreach (string directory in directories) { fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly); if (fileSystemEntries.Any()) continue; Directory.SetLastWriteTime(directory, dateTime); } } internal static string GetRelativePath(string path, int length, bool forceExtensionToLower) { string result; if (forceExtensionToLower) { string extension = Path.GetExtension(path); string extensionLowered = Path.GetExtension(path).ToLower(); if (extension != extensionLowered) { string? directoryName = Path.GetDirectoryName(path); if (string.IsNullOrEmpty(directoryName)) throw new NullReferenceException(directoryName); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path); if (string.IsNullOrEmpty(fileNameWithoutExtension)) throw new NullReferenceException(fileNameWithoutExtension); path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}"); } } result = path[length..].Replace(@"\", "/"); return result; } internal static string GetDirectory(string sourceDirectory, int level, string directoryName) { string result; string? checkDirectory; checkDirectory = Path.GetDirectoryName(sourceDirectory); for (int i = 0; i < level; i++) checkDirectory = Path.GetDirectoryName(checkDirectory); if (string.IsNullOrEmpty(checkDirectory)) throw new Exception(); checkDirectory = Path.Combine(checkDirectory, directoryName); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); result = checkDirectory; return result; } internal static (int level, List directories) Get(string rootDirectory, string sourceDirectory) { int result = 0; string? directory; string? checkDirectory; List results = []; checkDirectory = sourceDirectory; for (int i = 0; i < int.MaxValue; i++) { result += 1; directory = Path.GetFileName(checkDirectory); if (string.IsNullOrEmpty(directory)) break; results.Add(directory); checkDirectory = Path.GetDirectoryName(checkDirectory); if (checkDirectory == rootDirectory) break; } results.Reverse(); return new(result, results); } internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) { CombinedEnumAndIndex result; if (filePath.Id is not null) result = GetCombinedEnumAndIndex(propertyConfiguration, filePath, filePath.Id.Value.ToString()); else result = GetCombinedEnumAndIndex(propertyConfiguration, filePath, filePath.FileNameFirstSegment); return result; } internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches) { bool result; string text; if (!compareBeforeWrite) result = true; else { if (!File.Exists(path)) text = string.Empty; else text = File.ReadAllText(path); result = text != contents; if (!result && updateDateWhenMatches) { if (updateToWhenMatches is null) File.SetLastWriteTime(path, DateTime.Now); else File.SetLastWriteTime(path, updateToWhenMatches.Value); } } if (result) { if (path.Contains("()")) File.WriteAllText(path, contents); else if (path.Contains("{}") && !path.EndsWith(".json")) File.WriteAllText(path, contents); else if (path.Contains("[]") && !path.EndsWith(".json")) File.WriteAllText(path, contents); else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{') File.WriteAllText(path, contents); else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[') File.WriteAllText(path, contents); else File.WriteAllText(path, contents); } return result; } internal static ReadOnlyDictionary>> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) { Dictionary>> results = []; int plusOne; string directory; string checkDirectory; CombinedEnumAndIndex cei; byte[] bytes = GetBytes(); List collection; ReadOnlyDictionary> keyValuePairs; int converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}"); if (jsonGroups is not null) { plusOne = converted + 1; foreach (string jsonGroup in jsonGroups) { collection = []; if (resultsFullGroupDirectory is null) continue; foreach (byte @enum in bytes) { for (int i = 0; i < plusOne; i++) { if (string.IsNullOrEmpty(jsonGroup)) { if (i == converted) checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, $"{@enum}{new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)}")); else checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, $"{@enum}{i.ToString().PadLeft(propertyConfiguration.ResultAllInOneSubdirectoryLength, '0')}")); } else { directory = Path.Combine(resultsFullGroupDirectory, jsonGroup); if (i == converted) checkDirectory = Path.GetFullPath(Path.Combine(directory, $"{@enum}{new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)}")); else checkDirectory = Path.GetFullPath(Path.Combine(directory, $"{@enum}{i.ToString().PadLeft(propertyConfiguration.ResultAllInOneSubdirectoryLength, '0')}")); } if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); cei = new(Combined: checkDirectory, Enum: @enum, Index: -1); collection.Add(cei); } } keyValuePairs = Convert(collection); if (!string.IsNullOrEmpty(jsonGroup)) results.Add(jsonGroup, keyValuePairs); else results.Add(propertyConfiguration.ResultAllInOne, keyValuePairs); } } return results.AsReadOnly(); } private static byte[] GetBytes() => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; private static ReadOnlyDictionary> Convert(Dictionary> keyValuePairs) { Dictionary> results = []; foreach (KeyValuePair> keyValuePair in keyValuePairs) results.Add(keyValuePair.Key, new(keyValuePair.Value)); return results.AsReadOnly(); } }