using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models; using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Wafer.Counter.Helper; using OI.Metrology.Wafer.Counter.Models; using System.Collections.ObjectModel; using System.Globalization; using System.Text.Json; using System.Text.RegularExpressions; namespace OI.Metrology.Wafer.Counter.Repository; public class WaferCounterRepository : IWaferCounterRepository { private record Record(int Check, int Total, string? SlotMap); private readonly Regex _Regex; private readonly string _MockRoot; private readonly string _RepositoryName; private readonly AppSettings _AppSettings; private readonly IHttpClientFactory _HttpClientFactory; private readonly IFileShareRepository _FileShareRepository; public WaferCounterRepository(AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository) { _AppSettings = appSettings; _MockRoot = appSettings.MockRoot; _HttpClientFactory = httpClientFactory; _Regex = RegexHelper.WindowsFileSystem(); _FileShareRepository = fileShareRepository; _RepositoryName = nameof(WaferCounterRepository)[..^10]; } private void MoveFile(string area, string waferSize, WaferCounter? waferCounter, string windowsFileSystemSafeText, string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable) { string equipmentId = $"{area}-{waferSize}"; WaferCounterArchive waferCounterArchive = new() { Date = nginxFileSystemSortable.DateTime, MesEntity = equipmentId, RDS = windowsFileSystemSafeText, SlotMap = waferCounter?.SlotMap, Text = waferCounter?.Text, Total = waferCounter?.Total, }; Calendar calendar = new CultureInfo("en-US").Calendar; string from = Path.Combine(waferSizeDirectory, nginxFileSystemSortable.Name); string archive = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive", equipmentId); string weekOfYear = $"{nginxFileSystemSortable.DateTime:yyyy}_Week_{calendar.GetWeekOfYear(nginxFileSystemSortable.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; string directory = Path.Combine(archive, weekOfYear, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd"), windowsFileSystemSafeText); string file = Path.Combine(directory, nginxFileSystemSortable.DateTime.Ticks.ToString(), $"{nginxFileSystemSortable.Name}.json"); string json = JsonSerializer.Serialize(waferCounterArchive, WaferCounterArchiveSourceGenerationContext.Default.WaferCounterArchive); _FileShareRepository.FileWrite(file, json); string to = Path.Combine(directory, nginxFileSystemSortable.Name); _FileShareRepository.MoveFile(from, to); } private static Record GetRecord(string line1, string line2) { Record result; string? slotMap = string.IsNullOrEmpty(line2) || line2.Length != 8 ? null : line2.Substring(1, 1); int check = slotMap == "1" ? 1 : 0; #pragma warning disable IDE0057 int total = int.Parse(line1.Substring(1)); foreach (char item in line2.Substring(2)) #pragma warning restore IDE0057 { switch (item) { case '0': check += 0; slotMap += "0000"; break; case '1': check += 1; slotMap += "0001"; break; case '2': check += 1; slotMap += "0010"; break; case '3': check += 2; slotMap += "0011"; break; case '4': check += 1; slotMap += "0100"; break; case '5': check += 2; slotMap += "0101"; break; case '6': check += 2; slotMap += "0110"; break; case '7': check += 3; slotMap += "0111"; break; case '8': check += 1; slotMap += "1000"; break; case '9': check += 2; slotMap += "1001"; break; case 'A': check += 2; slotMap += "1010"; break; case 'B': check += 3; slotMap += "1011"; break; case 'C': check += 2; slotMap += "1100"; break; case 'D': check += 3; slotMap += "1101"; break; case 'E': check += 3; slotMap += "1110"; break; case 'F': check += 4; slotMap += "1111"; break; default: break; } } result = new(check, total, slotMap); return result; } private Uri GetWaferSizeUri(string area, string waferSize) => _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareCharacterizationSi), "WaferCounter", area, waferSize); private string GetWaferSizeDirectory(string area, string waferSize, bool destination) => destination ? Path.Combine(_AppSettings.WaferCounterDestinationDirectory, area, waferSize) : Path.Combine(_AppSettings.EcCharacterizationSi, "WaferCounter", area, waferSize); string? IWaferCounterRepository.GetSlotMap(string line1, string line2) => GetRecord(line1, line2).SlotMap; private List GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri waferSizeUri) { List results = new(); DateTime dateTime = DateTime.Now; ReadOnlyCollection collection; long ticks = dateTime.AddSeconds(_AppSettings.WaferCounterTwoFileSecondsWait).Ticks; for (int i = 0; i < int.MaxValue; i++) { collection = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, waferSizeUri, ".wc"); results.AddRange(collection); if (results.Count > 0 || DateTime.Now.Ticks > ticks) break; Thread.Sleep(250); } return results; } private static WaferCounter? GetLastQuantityAndSlotMap(string waferSize, HttpClient httpClient, NginxFileSystemSortable nginxFileSystemSortable) { WaferCounter? result; Task value = httpClient.GetStringAsync(nginxFileSystemSortable.Uri); value.Wait(); string[] lines = value.Result.Split("\r\n"); if (lines.Length < 3) result = WaferCounter.GetWaferCounter("Incomplete file length!"); else { string text = string.Empty; string[] segments = nginxFileSystemSortable.Name.Split('-'); Record record = GetRecord(lines[^3], lines[^2]); string equipmentId = segments.Length <= 1 ? nginxFileSystemSortable.Name : segments[1].Split('.')[0]; if (string.IsNullOrEmpty(record.SlotMap) || record.SlotMap.Length != 25) result = WaferCounter.GetWaferCounter("Wrong length for slot-map!"); else { if (record.Total != record.Check) result = WaferCounter.GetWaferCounter($"Checksum has failed. {record.Total} != {record.Check}"); else result = new(nginxFileSystemSortable.DateTime, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd hh:mm tt"), $"WC{waferSize}{equipmentId}", string.Empty, text, record.Total, record.SlotMap); } } return result; } WaferCounter? IWaferCounterRepository.GetLastQuantityAndSlotMap(string area, string waferSize, string text) { WaferCounter? result; Uri waferSizeUri = GetWaferSizeUri(area, waferSize); HttpClient httpClient = _HttpClientFactory.CreateClient(); string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false); List nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(httpClient, waferSizeUri); if (nginxFileSystemSortableCollection.Count < 1) result = WaferCounter.GetWaferCounter("No files!"); else { string windowsFileSystemSafeText = _Regex.Replace(text, "."); result = GetLastQuantityAndSlotMap(waferSize, httpClient, nginxFileSystemSortableCollection[0]); for (int i = 0; i < nginxFileSystemSortableCollection.Count; i++) MoveFile(area, waferSize, result, windowsFileSystemSafeText, waferSizeDirectory, nginxFileSystemSortableCollection[i]); } return result; } }