using OI.Metrology.Server.Models; using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Repositories; using System.Globalization; using System.Text.Json; namespace OI.Metrology.Server.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 IDbConnectionFactory _DBConnectionFactory; private readonly string _OpenInsightApplicationProgrammingInterface; public WaferCounterRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory) { _AppSettings = appSettings; _MockRoot = appSettings.MockRoot; _HttpClientFactory = httpClientFactory; _DBConnectionFactory = dbConnectionFactory; _RepositoryName = nameof(WaferCounterRepository)[..^10]; _OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface; } private static void MoveFile(string waferSizeDirectory, FileInfo fileInfo) { Calendar calendar = new CultureInfo("en-US").Calendar; string weekOfYear = $"{fileInfo.LastWriteTime:yyyy}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; string checkDirectory = Path.Combine(waferSizeDirectory, "Archive", weekOfYear); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); string checkFile = Path.Combine(checkDirectory, fileInfo.Name); if (!File.Exists(checkFile)) File.Move(fileInfo.FullName, checkFile); } private static Record GetRecord(string line1, string line2) { Record result; string? waferMap = string.IsNullOrEmpty(line2) || line2.Length != 8 ? null : line2.Substring(1, 1); int check = waferMap == "1" ? 1 : 0; int total = int.Parse(line1[1..]); // string wafers = Array.from(line2[2..]); foreach (char item in line2[2..]) { switch (item) { case '0': check += 0; waferMap += "0000"; break; case '1': check += 1; waferMap += "0001"; break; case '2': check += 1; waferMap += "0010"; break; case '3': check += 2; waferMap += "0011"; break; case '4': check += 1; waferMap += "0100"; break; case '5': check += 2; waferMap += "0101"; break; case '6': check += 2; waferMap += "0110"; break; case '7': check += 3; waferMap += "0111"; break; case '8': check += 1; waferMap += "1000"; break; case '9': check += 2; waferMap += "1001"; break; case 'A': check += 2; waferMap += "1010"; break; case 'B': check += 3; waferMap += "1011"; break; case 'C': check += 2; waferMap += "1100"; break; case 'D': check += 3; waferMap += "1101"; break; case 'E': check += 3; waferMap += "1110"; break; case 'F': check += 4; waferMap += "1111"; break; default: break; } } result = new(check, total, waferMap); return result; } private string GetWaferSizeDirectory(string area, string waferSize, bool destination) => destination ? Path.Combine(_AppSettings.WaferCounterDestinationDirectory, area, waferSize) : Path.Combine(_AppSettings.WaferCounterRootDirectory, area, waferSize); string? IWaferCounterRepository.GetSlotMap(string line1, string line2) => GetRecord(line1, line2).SlotMap; private static FileInfo[] GetFileInfoCollection(string waferSizeDirectory) { List results = new(); FileInfo[] fileInfoCollection; string[] files = !Directory.Exists(waferSizeDirectory) ? Array.Empty() : Directory.GetFiles(waferSizeDirectory, "*.wc", SearchOption.TopDirectoryOnly); fileInfoCollection = (from l in files select new FileInfo(l)).OrderByDescending(l => l.LastWriteTime).ToArray(); if (fileInfoCollection.Length > 0) results.Add(fileInfoCollection[0]); for (int i = 1; i < fileInfoCollection.Length; i++) MoveFile(waferSizeDirectory, fileInfoCollection[i]); return fileInfoCollection; } private static WaferCounter? GetLastQuantityAndSlotMapWithText(string waferSize, string text, FileInfo fileInfo) { WaferCounter? result; string[] lines = File.ReadAllLines(fileInfo.FullName); if (lines.Length < 2) result = null; else { string[] segments = fileInfo.Name.Split('-'); Record record = GetRecord(lines[0], lines[1]); string equipmentId = segments.Length < 2 ? fileInfo.Name : segments[1].Split('.')[0]; if (string.IsNullOrEmpty(record.SlotMap) || record.SlotMap.Length != 25) result = null; // Wrong length! else if (record.Total != record.Check) result = null; // Invalid! else result = new(fileInfo.LastWriteTime, fileInfo.LastWriteTime.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; if (!string.IsNullOrEmpty(_MockRoot)) { string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IWaferCounterRepository.GetLastQuantityAndSlotMap)}.json")); result = JsonSerializer.Deserialize(json); if (result is null) throw new NullReferenceException(nameof(result)); } else { string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false); FileInfo[] fileInfoCollection = GetFileInfoCollection(waferSizeDirectory); if (fileInfoCollection.Length == 0) result = null; else { string text = string.Empty; result = GetLastQuantityAndSlotMapWithText(waferSize, text, fileInfoCollection[0]); } } return result; } private static void Save(string waferSizeDestinationDirectory, string area, string waferSize, string text, FileInfo fileInfo, WaferCounter result) => File.WriteAllText(Path.Combine(waferSizeDestinationDirectory, $"{fileInfo.Name}.csv"), $"100,{waferSize},{area},{fileInfo.LastWriteTime},{text},{result.Total:00},{result.SlotMap} "); WaferCounter? IWaferCounterRepository.GetLastQuantityAndSlotMapWithText(string area, string waferSize, string text) { WaferCounter? result; if (!string.IsNullOrEmpty(_MockRoot)) { string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IWaferCounterRepository.GetLastQuantityAndSlotMapWithText)}.json")); result = JsonSerializer.Deserialize(json); if (result is null) throw new NullReferenceException(nameof(result)); } else { string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false); FileInfo[] fileInfoCollection = GetFileInfoCollection(waferSizeDirectory); if (fileInfoCollection.Length == 0) result = null; else { result = GetLastQuantityAndSlotMapWithText(waferSize, text, fileInfoCollection[0]); if (result is not null) { string waferSizeDestinationDirectory = _AppSettings.WaferCounterDestinationDirectory; // string waferSizeDestinationDirectory = GetWaferSizeDirectory(area, waferSize, destination: true); Save(waferSizeDestinationDirectory, area, waferSize, text, fileInfoCollection[0], result); } } } return result; } }