using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models; using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Wafer.Counter.Models; using System.Collections.ObjectModel; using System.Globalization; using System.Text.Json; namespace OI.Metrology.Wafer.Counter.Repository; public class FileShareRepository : IFileShareRepository { private readonly AppSettings _AppSettings; public FileShareRepository(AppSettings appSettings) => _AppSettings = appSettings; Uri IFileShareRepository.Append(Uri uri, params string[] paths) => new(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/')))); private Uri GetEndPoint(HttpClient httpClient, string method) { Uri result; if (httpClient.BaseAddress is null) throw new NullReferenceException(nameof(httpClient.BaseAddress)); IFileShareRepository fileShareRepository = this; result = fileShareRepository.Append(httpClient.BaseAddress, "api", "v1", "file-share", method); return result; } void IFileShareRepository.CopyFile(string from, string to) { string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException(); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); File.Copy(from, to); } void IFileShareRepository.MoveFile(string from, string to) { string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException(); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); if (File.Exists(to)) File.Move(to, $"{to}.{DateTime.Now.Ticks}.old"); File.Move(from, to); } void IFileShareRepository.FileWrite(string path, string contents) { string directory = Path.GetDirectoryName(path) ?? throw new NullReferenceException(); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); File.WriteAllText(path, contents); } void IFileShareRepository.CopyFile(HttpClient httpClient, string from, string to) { Uri uri = GetEndPoint(httpClient, "copy-file"); Task httpResponseMessage = httpClient.GetAsync(uri); httpResponseMessage.Wait(); if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception(httpResponseMessage.Result.StatusCode.ToString()); } void IFileShareRepository.MoveFile(HttpClient httpClient, string from, string to) { Uri uri = GetEndPoint(httpClient, "move-file"); Task httpResponseMessage = httpClient.GetAsync(uri); httpResponseMessage.Wait(); if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception(httpResponseMessage.Result.StatusCode.ToString()); } HttpResponseMessage IFileShareRepository.ReadFile(HttpClient httpClient, Uri uri) { HttpResponseMessage result; Task httpResponseMessage = httpClient.GetAsync(uri); httpResponseMessage.Wait(); result = httpResponseMessage.Result; return result; } ReadOnlyCollection IFileShareRepository.GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith) { List results = new(); Task httpResponseMessage = httpClient.GetAsync(uri); httpResponseMessage.Wait(); if (httpResponseMessage.Result.StatusCode == System.Net.HttpStatusCode.OK) { FileShareRepository fileShareRepository = this; Task json = httpResponseMessage.Result.Content.ReadAsStringAsync(); json.Wait(); NginxFileSystem[]? nginxFileSystemCollection = JsonSerializer.Deserialize(json.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray); List nginxFileSystemSortableCollection = NginxFileSystemSortable.Convert(fileShareRepository, uri, nginxFileSystemCollection); foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection.OrderByDescending(l => l.DateTime)) { if (!string.IsNullOrEmpty(endsWith) && !nginxFileSystemSortable.Name.EndsWith(endsWith)) continue; results.Add(nginxFileSystemSortable); } } return new(results); } private static ReadOnlyCollection GetValidDirectories(string equipmentDirectory, DateTime startDateTime, DateTime endDateTime) { List results = []; DateTime dateTime; string weekOfYear; Calendar calendar = new CultureInfo("en-US").Calendar; for (int i = 0; i < int.MaxValue; i++) { dateTime = startDateTime.AddDays(i); if (dateTime > endDateTime) break; weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; results.Add(Path.Combine(equipmentDirectory, weekOfYear, dateTime.ToString("yyyy-MM-dd"))); } return new(results); } private static ReadOnlyCollection GetFiles(CharacterizationParameters characterizationParameters, string equipmentDirectory, string searchPattern, DateTime startDateTime, DateTime endDateTime, ReadOnlyCollection validDirectories) { List results = []; string[] directories; string startDateTimeTicks = startDateTime.Ticks.ToString(); string delta = (endDateTime.Ticks - startDateTime.Ticks).ToString(); string ticksSearchPattern = $"{startDateTime.Ticks.ToString()[..(startDateTimeTicks.Length - delta.Length - 1)]}*"; bool check = characterizationParameters.SearchPattern is null || searchPattern == characterizationParameters.SearchPattern; if (check) results.AddRange(Directory.GetFiles(equipmentDirectory, searchPattern, SearchOption.AllDirectories)); foreach (string validDirectory in validDirectories) { if (string.IsNullOrEmpty(validDirectory) || !Directory.Exists(validDirectory)) continue; if (check) results.AddRange(Directory.GetFiles(validDirectory, searchPattern, SearchOption.AllDirectories)); else { directories = Directory.GetDirectories(validDirectory, ticksSearchPattern, SearchOption.AllDirectories); foreach (string directory in directories) results.AddRange(Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly)); } } return new(results); } private static ReadOnlyCollection GetCollection(CharacterizationParameters characterizationParameters, string equipmentDirectory, string searchPattern, DateTime startDateTime, DateTime endDateTime, ReadOnlyCollection validDirectories) { FileInfo[] results; ReadOnlyCollection files = GetFiles(characterizationParameters, equipmentDirectory, searchPattern, startDateTime, endDateTime, validDirectories); FileInfo[] collection = files.Select(l => new FileInfo(l)).ToArray(); results = (from l in collection where l.LastWriteTime >= startDateTime && l.LastWriteTime <= endDateTime orderby l.LastWriteTime descending select l).ToArray(); return new(results); } private static ReadOnlyCollection GetDirectoryNames(string directory) { List results = new(); 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 new(results); } private static ReadOnlyCollection GetCharacterizationData(CharacterizationParameters characterizationParameters, string equipmentDirectory, string searchPattern) { List results = []; string[] lines; string? directoryName; string? checkDirectory; CharacterizationInfo archiveInfo; ReadOnlyCollection directoryNames; DateTime endDateTime = characterizationParameters.EndTime is null ? DateTime.Now : DateTime.Parse(characterizationParameters.EndTime).ToLocalTime(); DateTime startDateTime = characterizationParameters.StartTime is null ? DateTime.Now.AddHours(-6) : DateTime.Parse(characterizationParameters.StartTime).ToLocalTime(); ReadOnlyCollection validDirectories = GetValidDirectories(equipmentDirectory, startDateTime, endDateTime); ReadOnlyCollection collection = GetCollection(characterizationParameters, equipmentDirectory, searchPattern, startDateTime, endDateTime, validDirectories); foreach (FileInfo fileInfo in collection) { if (string.IsNullOrEmpty(fileInfo.DirectoryName)) continue; checkDirectory = fileInfo.DirectoryName; directoryName = Path.GetFileName(fileInfo.DirectoryName); directoryNames = GetDirectoryNames(fileInfo.DirectoryName); foreach (string _ in directoryNames) { if (string.IsNullOrEmpty(checkDirectory)) continue; if (validDirectories.Contains(checkDirectory)) { directoryName = Path.GetFileName(checkDirectory); break; } } lines = File.ReadAllLines(fileInfo.FullName); archiveInfo = new(directoryName, fileInfo.LastWriteTime, lines); results.Add(archiveInfo); } return new(results); } ReadOnlyCollection IFileShareRepository.GetArchiveData(CharacterizationParameters characterizationParameters) { List results = []; string searchPattern; string equipmentDirectory; if (!string.IsNullOrEmpty(characterizationParameters.Area) && !string.IsNullOrEmpty(characterizationParameters.WaferSize)) { searchPattern = characterizationParameters.SearchPattern is null ? "*" : characterizationParameters.SearchPattern; equipmentDirectory = Path.Combine(_AppSettings.EcCharacterizationSi, "WaferCounter", characterizationParameters.Area, characterizationParameters.WaferSize); if (Directory.Exists(equipmentDirectory)) results.AddRange(GetCharacterizationData(characterizationParameters, equipmentDirectory, searchPattern)); } if (!string.IsNullOrEmpty(characterizationParameters.EquipmentId)) { searchPattern = "*.json"; equipmentDirectory = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive", characterizationParameters.EquipmentId); if (Directory.Exists(equipmentDirectory)) results.AddRange(GetCharacterizationData(characterizationParameters, equipmentDirectory, searchPattern)); } return new(results); } ReadOnlyCollection IFileShareRepository.GetEquipmentIds() { List results = []; string directoryName; ToolTypeNameId toolTypeNameId; string archiveDirectory = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive"); string[] directories = Directory.GetDirectories(archiveDirectory, "*", SearchOption.TopDirectoryOnly); string[] fileNames = Directory.GetFiles(archiveDirectory, "*.json", SearchOption.TopDirectoryOnly).Select(l => Path.GetFileNameWithoutExtension(l)).ToArray(); for (int i = 0; i < directories.Length; i++) { directoryName = Path.GetFileName(directories[i]); if (!fileNames.Contains(directoryName)) continue; toolTypeNameId = new() { ID = i, ToolTypeName = directoryName }; results.Add(toolTypeNameId); } return new(results); } }