using System.Collections.ObjectModel; namespace View_by_Distance.Shared.Models.Stateless; internal abstract class XPath { 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 bool DeleteEmptyDirectories(string rootDirectory) { bool result; List results = []; DeleteEmptyDirectories(rootDirectory, results); result = results.Count > 0; return result; } 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 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 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 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 (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 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 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 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; } } private static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileNameWithoutExtension) { int converted; string result; string fileNameBeforeFirst = fileNameWithoutExtension.Split('.')[0]; string check = fileNameBeforeFirst.Length < resultAllInOneSubdirectoryLength ? new('-', resultAllInOneSubdirectoryLength) : fileNameBeforeFirst[^resultAllInOneSubdirectoryLength..]; if (check.Any(l => !char.IsNumber(l))) { result = new('-', resultAllInOneSubdirectoryLength); converted = int.Parse($"1{new string('0', resultAllInOneSubdirectoryLength)}"); } else { result = check; converted = int.Parse(check); } return new(result, converted); } internal static (string, int) GetDirectoryNameAndIndex(ResultSettings resultSettings, int id) { (string result, int converted) = GetDirectoryNameAndIndex(resultSettings.ResultAllInOneSubdirectoryLength, id.ToString()); return new(result, converted); } internal static (string, int) GetDirectoryNameAndIndex(ResultSettings resultSettings, FileHolder fileHolder) { (string result, int converted) = GetDirectoryNameAndIndex(resultSettings.ResultAllInOneSubdirectoryLength, fileHolder.NameWithoutExtension); return new(result, converted); } internal static (string, int) GetDirectoryNameAndIndex(ResultSettings resultSettings, FilePath filePath) { string result; int converted; if (filePath.Id is not null) (result, converted) = GetDirectoryNameAndIndex(resultSettings.ResultAllInOneSubdirectoryLength, filePath.Id.Value.ToString()); else (result, converted) = GetDirectoryNameAndIndex(resultSettings.ResultAllInOneSubdirectoryLength, filePath.NameWithoutExtension); return new(result, converted); } private static ReadOnlyCollection GetYears(ResultSettings resultSettings) { List results = []; int currentYear = DateTime.Now.Year; for (int i = resultSettings.EpicYear; i < currentYear + 1; i++) results.Add(i); return results.AsReadOnly(); } private static ReadOnlyDictionary> Convert(Dictionary> collection) { Dictionary> results = []; foreach (KeyValuePair> keyValuePair in collection) results.Add(keyValuePair.Key, new(keyValuePair.Value)); return results.AsReadOnly(); } internal static ReadOnlyDictionary> GetKeyValuePairs(ResultSettings resultSettings, string? resultsFullGroupDirectory, string[]? jsonGroups) { Dictionary> results = []; string directory; string checkDirectory; Dictionary? keyValuePairs; ReadOnlyCollection years = GetYears(resultSettings); int converted = int.Parse($"1{new string('0', resultSettings.ResultAllInOneSubdirectoryLength)}"); int plusOne = converted + 1; List collection = []; foreach (int year in years) { results.Add(year, []); if (!results.TryGetValue(year, out keyValuePairs)) throw new NullReferenceException(nameof(keyValuePairs)); if (jsonGroups is not null) { foreach (string jsonGroup in jsonGroups) { if (resultsFullGroupDirectory is null) continue; collection.Clear(); for (int i = 0; i < plusOne; i++) { if (string.IsNullOrEmpty(jsonGroup)) { if (i == converted) checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, new('-', resultSettings.ResultAllInOneSubdirectoryLength))); else checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, i.ToString().PadLeft(resultSettings.ResultAllInOneSubdirectoryLength, '0'))); } else { directory = Path.Combine(resultsFullGroupDirectory, jsonGroup); if (i == converted) checkDirectory = Path.GetFullPath(Path.Combine(directory, new('-', resultSettings.ResultAllInOneSubdirectoryLength))); else checkDirectory = Path.GetFullPath(Path.Combine(directory, i.ToString().PadLeft(resultSettings.ResultAllInOneSubdirectoryLength, '0'))); } if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); collection.Add(checkDirectory); } if (!string.IsNullOrEmpty(jsonGroup)) keyValuePairs.Add(jsonGroup, collection.ToArray()); else keyValuePairs.Add(year.ToString(), collection.ToArray()); } } } return Convert(results); } }