using OI.Metrology.Wafer.Counter.Models; using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models; using OI.Metrology.Shared.Models.Stateless; using System.Globalization; namespace OI.Metrology.Wafer.Counter.Repository; public class WaferCounterRepository : IWaferCounterRepository { private record Record(int Check, int Total, string? SlotMap); 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; _FileShareRepository = fileShareRepository; _RepositoryName = nameof(WaferCounterRepository)[..^10]; } private void MoveFile(string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable) { Calendar calendar = new CultureInfo("en-US").Calendar; string from = Path.Combine(waferSizeDirectory, nginxFileSystemSortable.Name); string weekOfYear = $"{nginxFileSystemSortable.DateTime:yyyy}_Week_{calendar.GetWeekOfYear(nginxFileSystemSortable.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; string to = Path.Combine(waferSizeDirectory, "Archive", weekOfYear, 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; long ticks = dateTime.AddSeconds(_AppSettings.WaferCounterTwoFileSecondsWait).Ticks; for (int i = 0; i < int.MaxValue; i++) { results = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, waferSizeUri, ".wc"); 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; string text = string.Empty; Task value = httpClient.GetStringAsync(nginxFileSystemSortable.Uri); value.Wait(); string[] lines = value.Result.Split("\r\n"); if (lines.Length <= 1) throw new Exception("Incomplete file length!"); string[] segments = nginxFileSystemSortable.Name.Split('-'); Record record = GetRecord(lines[0], lines[1]); string equipmentId = segments.Length <= 1 ? nginxFileSystemSortable.Name : segments[1].Split('.')[0]; if (string.IsNullOrEmpty(record.SlotMap) || record.SlotMap.Length != 25) throw new Exception("Wrong length for slot-map!"); if (record.Total != record.Check) throw new Exception($"Checksum has failed. {record.Total} != {record.Check}"); result = new(nginxFileSystemSortable.DateTime, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd hh:mm tt"), $"WC{waferSize}{equipmentId}", text, record.Total, record.SlotMap); return result; } WaferCounter IWaferCounterRepository.GetLastQuantityAndSlotMap(string area, string waferSize) { 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) throw new Exception("No files!"); result = GetLastQuantityAndSlotMap(waferSize, httpClient, nginxFileSystemSortableCollection[0]); for (int i = 0; i < nginxFileSystemSortableCollection.Count; i++) MoveFile(waferSizeDirectory, nginxFileSystemSortableCollection[i]); return result; } }