using System.Collections.ObjectModel; using Microsoft.Extensions.Logging; namespace File_Folder_Helper.ADO2025.PI6; internal static partial class Helper20250618 { private record Record(string Directory, List Files); internal static void MoveAllButXOfEach(ILogger logger, List args) { int keep = int.Parse(args[5]); logger.LogInformation(args[0]); logger.LogInformation(args[1]); logger.LogInformation(args[2]); string searchPattern = args[2]; string split = args[4].Split('~')[0]; string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]); string destinationDirectory = Path.GetFullPath(args[3].Split('~')[0]); if (destinationDirectory.Contains(sourceDirectory)) { throw new Exception("Not allowed!"); } ReadOnlyCollection directories = GetDirectories(sourceDirectory); MoveAllButXOfEachB(logger, searchPattern, sourceDirectory, destinationDirectory, split, keep, directories); } private static ReadOnlyCollection GetDirectories(string sourceDirectory) { List results = [sourceDirectory]; results.AddRange(Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories)); return results.AsReadOnly(); } private static void MoveAllButXOfEachB(ILogger logger, string searchPattern, string sourceDirectory, string destinationDirectory, string split, int keep, ReadOnlyCollection directories) { string[] files; int sourceDirectoryLength = sourceDirectory.Length; ReadOnlyDictionary> keyValuePairs; foreach (string directory in directories) { files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); keyValuePairs = GetFiles(split, files); foreach (KeyValuePair> keyValuePair in keyValuePairs) { if (keyValuePair.Value.Count <= keep) { continue; } else { MoveAllButXOfEachC(logger, sourceDirectoryLength, destinationDirectory, keyValuePair); } } } } private static ReadOnlyDictionary> GetFiles(string split, string[] files) { Dictionary> results = []; string key; List? collection; Dictionary> keyValuePairs = []; foreach (string file in files) { key = Path.GetFileName(file).Split(split)[0]; if (!keyValuePairs.TryGetValue(key, out collection)) { keyValuePairs.Add(key, []); if (!keyValuePairs.TryGetValue(key, out collection)) { throw new Exception(); } } collection.Add(file); } foreach (KeyValuePair> keyValuePair in keyValuePairs) { results.Add(keyValuePair.Key, keyValuePair.Value.OrderByDescending(l => l).ToArray().AsReadOnly()); } return results.AsReadOnly(); } private static void MoveAllButXOfEachC(ILogger logger, int sourceDirectoryLength, string destinationDirectory, KeyValuePair> keyValuePair) { string file; string checkFile; string checkDirectory; for (int i = 1; i < keyValuePair.Value.Count; i++) { file = keyValuePair.Value[i]; checkFile = $"{destinationDirectory}{file[sourceDirectoryLength..]}"; checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new Exception(); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); if (File.Exists(checkFile)) continue; File.Move(file, checkFile); logger.LogInformation("<{file}> moved", file); } } }