using OI.Metrology.Server.Models; using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models; using OI.Metrology.Shared.Models.Stateless; using System.Data; using System.Globalization; using System.Text; using System.Text.Json; namespace OI.Metrology.Server.Repository; public class ExportRepository : IExportRepository { private readonly string _RepositoryName; private readonly AppSettings _AppSettings; private readonly ILogger _Logger; private readonly IHttpClientFactory _HttpClientFactory; private readonly IFileShareRepository _FileShareRepository; private readonly Dictionary> _RdsToHeaderCommonCollection; public ExportRepository(ILogger logger, AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository) { _Logger = logger; _AppSettings = appSettings; _RdsToHeaderCommonCollection = new(); _HttpClientFactory = httpClientFactory; _FileShareRepository = fileShareRepository; _RepositoryName = nameof(ExportRepository)[..^10]; } private static string[] Get() { DateTime dateTime = DateTime.Now; DateTime lastWeekDateTime = dateTime.AddDays(-7); Calendar calendar = new CultureInfo("en-US").Calendar; string weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; string lastWeekOfYear = $"{lastWeekDateTime:yyyy}_Week_{calendar.GetWeekOfYear(lastWeekDateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}"; return new string[] { weekOfYear, lastWeekOfYear }; } private NginxFileSystemSortable[] GetNginxFileSystemSortableCollection(HeaderCommon headerCommon, HttpClient httpClient, string endsWith) { List results = new(); Uri uri; string[] weeks = Get(); List nginxFileSystemSortableCollection; foreach (string weekYear in weeks) { if (headerCommon.ID < 1) uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}"); else uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}", $"-{headerCommon.ID}"); nginxFileSystemSortableCollection = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, uri, endsWith); results.AddRange(nginxFileSystemSortableCollection); } return results.OrderByDescending(l => l.DateTime).ToArray(); } private string GetLines(HttpClient httpClient, NginxFileSystemSortable[] nginxFileSystemSortableCollection) { string result; if (nginxFileSystemSortableCollection.Length != 1) result = string.Empty; else { HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, nginxFileSystemSortableCollection.First().Uri); if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception("File not found!"); Task lines = httpResponseMessage.Content.ReadAsStringAsync(); lines.Wait(); result = lines.Result; } return result; } string IExportRepository.GetExport(HeaderCommon headerCommon) { string result; HttpClient httpClient = _HttpClientFactory.CreateClient(); NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".txt"); result = GetLines(httpClient, nginxFileSystemSortableCollection); return result; } Result IExportRepository.GetHeaders(HeaderCommon headerCommon) { Result? result; List results = new(); string json; HeaderCommon? hc; string? directory; string directoryName; JsonElement? jsonElement; const string ticks = "Ticks"; JsonProperty[] jsonProperties; HttpClient httpClient = _HttpClientFactory.CreateClient(); NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json"); foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection) { json = GetLines(httpClient, nginxFileSystemSortableCollection); hc = JsonSerializer.Deserialize(json); if (hc is null) continue; if (hc.ID < 1) { directory = Path.GetDirectoryName(nginxFileSystemSortable.Uri.OriginalString); if (directory is null) continue; directoryName = Path.GetFileName(directory); if (directoryName.Length < 1 || directoryName[0] != '-' || !long.TryParse(directoryName[1..], out long id)) continue; hc.ID = id; } jsonElement = JsonSerializer.Deserialize(json); if (jsonElement is not null && jsonElement.Value.ValueKind == JsonValueKind.Object) { jsonProperties = (from l in jsonElement.Value.EnumerateObject() where l.Name == ticks select l).ToArray(); if (jsonProperties.Length != 0 && long.TryParse(jsonProperties[0].Value.ToString(), out long ticksValue)) hc.Date = new(ticksValue); } results.Add(hc); } result = new() { Results = results.ToArray(), TotalRows = results.Count, }; return result; } Result IExportRepository.GetLogistics(HeaderCommon headerCommon) { Result? result; List results = new(); string json; HeaderCommon? hc; HttpClient httpClient = _HttpClientFactory.CreateClient(); NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json"); foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection) { json = GetLines(httpClient, nginxFileSystemSortableCollection); hc = JsonSerializer.Deserialize(json); if (hc is null) continue; results.Add(hc); } result = new() { Results = results.ToArray(), TotalRows = results.Count, }; return result; } string IExportRepository.GetProcessDataStandardFormat(HeaderCommon headerCommon) { string result; HttpClient httpClient = _HttpClientFactory.CreateClient(); NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".pdsf"); result = GetLines(httpClient, nginxFileSystemSortableCollection); return result; } Result IExportRepository.GetExportData(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend) { Result? r; DateTime dateEnd = dateend is null ? DateTime.Now : DateTime.Parse(dateend); DateTime dateBegin = datebegin is null ? dateEnd.AddMonths(-1) : DateTime.Parse(datebegin); ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId); if (string.IsNullOrEmpty(tt.ExportSPName)) throw new NullReferenceException(nameof(tt.ExportSPName)); DataTable dataTable = metrologyRepository.ExportData(tt.ExportSPName, dateBegin, dateEnd); r = new() { Results = dataTable, TotalRows = dataTable.Rows.Count, }; return r; } protected static string FormatForCSV(string v) { StringBuilder result = new(v.Length + 2); bool doubleQuoted = false; if (v.StartsWith(' ') || v.EndsWith(' ') || v.Contains(',') || v.Contains('"')) { _ = result.Append('"'); doubleQuoted = true; } foreach (char c in v) { _ = c switch { '\r' or '\n' => result.Append(' '), '"' => result.Append("\"\""), _ => result.Append(c), }; } if (doubleQuoted) _ = result.Append('"'); return result.ToString(); } protected static string GetColumnHeaders(DataTable dataTable) { StringBuilder result = new(); for (int i = 0; i < dataTable.Columns.Count; i++) { if (i > 0) _ = result.Append(','); _ = result.Append(FormatForCSV(dataTable.Columns[i].ColumnName.TrimEnd('_'))); } return result.ToString(); } protected static string GetRowData(DataRow dr) { StringBuilder result = new(); for (int i = 0; i < dr.Table.Columns.Count; i++) { if (i > 0) _ = result.Append(','); object v = dr[i]; if (v is not null && !Convert.IsDBNull(v)) _ = result.Append(FormatForCSV(string.Concat(Convert.ToString(v)))); } return result.ToString(); } string IExportRepository.GetCSVExport(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend) { string results; Result result; IExportRepository repository = this; result = repository.GetExportData(metrologyRepository, toolTypeId, datebegin, dateend); if (result.Results is null) throw new NullReferenceException(nameof(result.Results)); StringBuilder stringBuilder = new(); _ = stringBuilder.AppendLine(GetColumnHeaders(result.Results)); foreach (DataRow dr in result.Results.Rows) _ = stringBuilder.AppendLine(GetRowData(dr)); results = stringBuilder.ToString(); return results; } }