using File_Folder_Helper.Helpers; using Microsoft.Extensions.Logging; using System.Collections.ObjectModel; using System.Text.Json; using System.Text.Json.Serialization; namespace File_Folder_Helper.ADO2024.PI2; internal static partial class Helper20240520 { private record RecordA(string Directory, string Extension, string SourceFile, Identifier Identifier); private record RecordB(ReadOnlyDictionary IdTo, ReadOnlyDictionary LengthTo, ReadOnlyDictionary PaddedTo); internal sealed record Identifier(int Id, long Length, string PaddedId, long Ticks) { public override string ToString() { string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier); return result; } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Identifier))] internal partial class IdentifierSourceGenerationContext : JsonSerializerContext { } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Identifier[]))] internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext { } private static RecordB GetRecordB(string jsonFile) { RecordB result; Dictionary idTo = []; Dictionary lengthTo = []; Dictionary paddedTo = []; string? json = !File.Exists(jsonFile) ? null : File.ReadAllText(jsonFile); Identifier[]? identifiers = json is null ? null : JsonSerializer.Deserialize(json, IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); if (identifiers is null && !string.IsNullOrEmpty(jsonFile)) throw new Exception($"Invalid {nameof(jsonFile)}"); if (identifiers is not null) { foreach (Identifier identifier in identifiers) { idTo.Add(identifier.Id, identifier); paddedTo.Add(identifier.PaddedId, identifier); if (lengthTo.ContainsKey(identifier.Length)) { _ = lengthTo.Remove(identifier.Length); continue; } lengthTo.Add(identifier.Length, identifier); } } result = new(new(idTo), new(lengthTo), new(paddedTo)); return result; } internal static void IdentifierRename(ILogger logger, List args) { int id; string key; RecordA recordA; string checkFile; FileInfo fileInfo; string checkDirectory; Identifier? identifier; string offset = args[5]; string option = args[7]; string jsonFile = args[4]; string fileNameWithoutExtension; List recordACollection = []; RecordB recordB = GetRecordB(jsonFile); string deterministicHashCode = args[3]; string source = Path.GetFullPath(args[0]); int intMinValueLength = int.Parse(args[2]); string destination = Path.GetFullPath(args[6]); bool isOffsetDeterministicHashCode = offset == deterministicHashCode; string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories); logger.LogInformation("Found {files}(s)", sourceFiles.Length); int sourceLength = source.Length; foreach (string sourceFile in sourceFiles) { fileInfo = new(sourceFile); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName); if (fileInfo.Directory is null) throw new NotSupportedException(); if (option == "Padded") { if (fileNameWithoutExtension.Length < intMinValueLength) continue; key = fileNameWithoutExtension; if (recordB.PaddedTo.TryGetValue(key, out identifier)) { recordACollection.Add(new($"{destination}{fileInfo.Directory.FullName[sourceLength..]}", fileInfo.Extension, fileInfo.FullName, identifier)); continue; } } if (option == "Length") { if (recordB.LengthTo.TryGetValue(fileInfo.Length, out identifier)) { checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}"; if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}"); if (File.Exists(checkFile)) continue; File.Copy(fileInfo.FullName, checkFile); logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile); continue; } } if (option == "Id") { if (int.TryParse(fileNameWithoutExtension, out id)) { if (recordB.IdTo.TryGetValue(id, out identifier)) { checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}"; if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}"); if (File.Exists(checkFile)) continue; File.Move(fileInfo.FullName, checkFile); logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile); continue; } } } } if (option == "Padded") { if (!isOffsetDeterministicHashCode) recordACollection = (from l in recordACollection orderby l.Identifier.Ticks select l).ToList(); for (int i = 0; i < recordACollection.Count; i++) { recordA = recordACollection[i]; if (!Directory.Exists(recordA.Directory)) _ = Directory.CreateDirectory(recordA.Directory); checkFile = Path.Combine(recordA.Directory, isOffsetDeterministicHashCode ? $"{recordA.Identifier.PaddedId}{recordA.Extension}" : $"{offset + i}{recordA.Identifier.PaddedId}{recordA.Extension}"); if (File.Exists(checkFile)) continue; File.Move(recordA.SourceFile, checkFile); logger.LogInformation("<{recordA.SourceFile}> was moved to <{checkFile}>", recordA.SourceFile, checkFile); } } HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, source); } }