using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; using DocumentFormat.OpenXml.Bibliography; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB; public class MessageRepository : IMessageRepository { private readonly IAsbCloudDbContext db; private readonly IMemoryCache memoryCache; private readonly ITelemetryService telemetryService; public MessageRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, ITelemetryService telemetryService) { this.db = db; this.memoryCache = memoryCache; this.telemetryService = telemetryService; } public async Task> GetMessagesAsync(MessageTelemetryRequest request, CancellationToken token) { var query = BuildQuery(request, token); var entities = await query.ToArrayAsync(token); var dtos = entities.Select(m => m.Adapt()); return dtos; } public async Task> GetPaginatedMessagesAsync(MessageTelemetryRequest request, CancellationToken token) { var result = new PaginationContainer { Skip = request.Skip ?? 0, Take = request.Take ?? 32, }; if (request.Telemetries.IsNullOrEmpty() || request.Events.IsNullOrEmpty()) return result; var query = BuildQuery(request, token); if (request.SortFields?.Any() == true) { query = query.SortBy(request.SortFields); } result.Count = query.Count(); var messagesList = await query .Skip(result.Skip) .Take(result.Take) .AsNoTracking() .ToArrayAsync(token); if (messagesList.Count() == 0) return result; var allUsers = await memoryCache.GetOrCreateBasicAsync(db.Set(), token); var users = allUsers.Where(u => request.Telemetries!.Select(t => t.Id).Contains(u.IdTelemetry)); if (!request.Events.Any()) return result; var eventsDict = request.Events.ToDictionary(x => x.Id); var usersDict = users.ToDictionary(x => x.IdUser, x => x); var messagesDtoList = new List(); foreach (var message in messagesList) { var messageDto = new MessageDto { Id = message.Id, WellDepth = message.WellDepth, }; var telemetry = request.Telemetries.Where(t => t.Id == message.IdTelemetry).FirstOrDefault(); if(telemetry != null && telemetry.TimeZone != null) messageDto.DateTime = message.DateTime.ToOffset(TimeSpan.FromHours(telemetry.TimeZone.Hours)); if (message.IdTelemetryUser is not null) { if (usersDict.TryGetValue((int)message.IdTelemetryUser, out TelemetryUser? user)) { messageDto.User = user.MakeDisplayName(); } else messageDto.User = message.IdTelemetryUser.ToString(); } if (eventsDict.TryGetValue(message.IdEvent, out TelemetryEventDto? e)) { messageDto.CategoryId = e.IdCategory; messageDto.Message = e.MakeMessageText([ message.Arg0, message.Arg1, message.Arg2, message.Arg3 ]); } messagesDtoList.Add(messageDto); } result.Items = result.Items.Concat(messagesDtoList); return result; } public IQueryable BuildQuery(MessageTelemetryRequest request, CancellationToken token) { var idsTelemetries = request.Telemetries.Select(t => t.Id); var eventIds = request.Events.Select(e => e.Id); var query = db.TelemetryMessages .Where(m => idsTelemetries.Contains(m.IdTelemetry)) .Where(m => eventIds.Contains(m.IdEvent)); if (request.Begin is not null) { var beginUtc = request.Begin.Value.ToUniversalTime(); query = query.Where(m => m.DateTime >= beginUtc); } if (request.End is not null) { var endUtc = request.End.Value.ToUniversalTime(); query = query.Where(m => m.DateTime <= endUtc); } query = query.OrderByDescending(m => m.DateTime); return query; } public Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (!dtos.Any()) return Task.CompletedTask; var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid); foreach (var dto in dtos) { var entity = dto.Adapt(); entity.Id = 0; entity.IdTelemetry = telemetry.Id; entity.DateTime = dto.Date.ToUniversalTime(); db.TelemetryMessages.Add(entity); } return db.SaveChangesAsync(token); } private IQueryable BuildQuery(TelemetryPartDeleteRequest request) { var query = db.Set() .Where(o => o.IdTelemetry == request.IdTelemetry); if (request.GeDate is not null) { var geDate = request.GeDate.Value.ToUniversalTime(); query = query.Where(o => o.DateTime <= geDate); } if (request.LeDate is not null) { var leDate = request.LeDate.Value.ToUniversalTime(); query = query.Where(o => o.DateTime >= leDate); } return query; } public async Task DeleteAsync(TelemetryPartDeleteRequest request, CancellationToken token) { var query = BuildQuery(request); db.Set().RemoveRange(query); return await db.SaveChangesAsync(token); } }