using Microsoft.Extensions.Logging; using Phares.Shared.Models; using Phares.Shared.Models.Stateless; using System.Collections.ObjectModel; using System.Text.Json; using System.Text.Json.Serialization; namespace File_Folder_Helper.ADO2025.PI6; internal static partial class Helper20250726 { private record Helper20250726Settings(ResultSettings? ResultSettings, MetadataSettings? MetadataSettings); private record Record(CombinedEnumAndIndex CombinedEnumAndIndex, FilePath FilePath, bool HasFlagHidden); [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Helper20250726Settings))] private partial class Helper20250726SettingsSourceGenerationContext : JsonSerializerContext { } internal static void CopyToCombinedEnumAndIndexFormat(ILogger logger, List args) { logger.LogInformation(args[0]); logger.LogInformation(args[1]); logger.LogInformation(args[2]); logger.LogInformation(args[3]); logger.LogInformation(args[4]); logger.LogInformation(args[5]); logger.LogInformation(args[6]); string[] files; string[] searchPatterns = args[4].Split('~'); string jsonFile = Path.GetFullPath(args[3]); if (!File.Exists(jsonFile)) { throw new Exception($"json file doesn't exist! <{jsonFile}>"); } ReadOnlyCollection records; string json = File.ReadAllText(jsonFile); string destinationDirectoryName = args[6]; ReadOnlyDictionary> keyValues; string sourceDirectory = Path.GetFullPath(args[0].Split('~')[0]); string destinationDirectory = Path.GetFullPath(args[5].Split('~')[0]); long maxSize = long.Parse(args[2], System.Globalization.NumberStyles.Float); ReadOnlyDictionary>> keyValuePairs; Helper20250726Settings? settings = JsonSerializer.Deserialize(json, Helper20250726SettingsSourceGenerationContext.Default.Helper20250726Settings); if (settings?.ResultSettings is null || settings.ResultSettings.ResultAllInOneSubdirectoryLength < 1 || settings.MetadataSettings is null) { throw new Exception(nameof(Helper20250726Settings)); } foreach (string searchPattern in searchPatterns) { files = Directory.GetFiles(sourceDirectory, $"*{searchPattern}", SearchOption.AllDirectories); if (files.Length == 0) { logger.LogInformation($"Didn't find any {searchPattern} files"); continue; } logger.LogInformation($"Found {files.Length} {searchPattern} files"); keyValuePairs = GetKeyValuePairs(settings.ResultSettings, destinationDirectory, destinationDirectoryName); records = GetRecords(logger, settings.ResultSettings, settings.MetadataSettings, files); keyValues = keyValuePairs.ElementAt(0).Value; CopyToCombinedEnumAndIndexFormat(logger, maxSize, records, keyValues); } Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, destinationDirectory); } private static ReadOnlyDictionary>> GetKeyValuePairs(ResultSettings resultSettings, string destinationDirectory, string destinationDirectoryName) { Dictionary>> results = []; ReadOnlyDictionary>>> keyValuePairs = IPath.GetKeyValuePairs(resultSettings, destinationDirectory, [destinationDirectoryName]); foreach (KeyValuePair>>> keyValuePair in keyValuePairs) { foreach (KeyValuePair>> keyValue in keyValuePair.Value) { if (keyValue.Key != destinationDirectoryName) throw new Exception("Never should happen!"); results.Add(keyValuePair.Key, keyValue.Value); } } return results.AsReadOnly(); } private static ReadOnlyCollection GetRecords(ILogger logger, ResultSettings resultSettings, MetadataSettings metadataSettings, string[] files) { List results = []; Record record; FileInfo fileInfo; FilePath filePath; bool hasFlagHidden; FileHolder fileHolder; CombinedEnumAndIndex combinedEnumAndIndex; foreach (string file in files) { fileInfo = new(file); fileHolder = FileHolder.Get(fileInfo, id: null); filePath = FilePath.Get(resultSettings, metadataSettings, fileHolder, index: null); if (!filePath.IsIntelligentIdFormat) { logger.LogWarning("<{file}> skipped because of name format!", filePath.Name); continue; } hasFlagHidden = fileInfo.Attributes.HasFlag(FileAttributes.Hidden); combinedEnumAndIndex = IPath.GetCombinedEnumAndIndex(resultSettings, filePath); record = new(CombinedEnumAndIndex: combinedEnumAndIndex, FilePath: filePath, HasFlagHidden: hasFlagHidden); results.Add(record); } return results.AsReadOnly(); } private static void CopyToCombinedEnumAndIndexFormat(ILogger logger, long maxSize, ReadOnlyCollection records, ReadOnlyDictionary> keyValuePairs) { string checkFile; FileInfo fileInfo; FileAttributes fileAttributes; foreach (Record record in records) { if (record.FilePath.Length > maxSize) { logger.LogWarning("<{file}> skipped because it is over {size}!", record.FilePath.Name, maxSize); continue; } checkFile = Path.Combine(keyValuePairs[record.CombinedEnumAndIndex.Enum][record.CombinedEnumAndIndex.Index], record.FilePath.Name); if (File.Exists(checkFile)) { logger.LogWarning("<{file}> skipped because it already exists!", record.FilePath.Name); continue; } File.Copy(record.FilePath.FullName, checkFile); if (record.HasFlagHidden) { fileInfo = new(checkFile); fileAttributes = fileInfo.Attributes & ~FileAttributes.Hidden; File.SetAttributes(fileInfo.FullName, fileAttributes); } } } }