using Microsoft.EntityFrameworkCore; using ScadaLink.Commons.Entities.Audit; using ScadaLink.Commons.Entities.Deployment; using ScadaLink.Commons.Entities.Instances; using ScadaLink.Commons.Entities.Sites; using ScadaLink.Commons.Entities.Templates; using ScadaLink.Commons.Interfaces.Repositories; namespace ScadaLink.ConfigurationDatabase.Repositories; public class CentralUiRepository : ICentralUiRepository { private readonly ScadaLinkDbContext _context; public CentralUiRepository(ScadaLinkDbContext context) { _context = context ?? throw new ArgumentNullException(nameof(context)); } public async Task> GetAllSitesAsync(CancellationToken cancellationToken = default) { return await _context.Sites .AsNoTracking() .OrderBy(s => s.Name) .ToListAsync(cancellationToken); } public async Task> GetDataConnectionsBySiteIdAsync(int siteId, CancellationToken cancellationToken = default) { return await _context.DataConnections .AsNoTracking() .Where(d => d.SiteId == siteId) .OrderBy(d => d.Name) .ToListAsync(cancellationToken); } public async Task> GetAllDataConnectionsAsync(CancellationToken cancellationToken = default) { return await _context.DataConnections .AsNoTracking() .OrderBy(d => d.Name) .ToListAsync(cancellationToken); } public async Task> GetTemplateTreeAsync(CancellationToken cancellationToken = default) { return await _context.Templates .AsNoTracking() .Include(t => t.Attributes) .Include(t => t.Alarms) .Include(t => t.Scripts) .Include(t => t.Compositions) .AsSplitQuery() .OrderBy(t => t.Name) .ToListAsync(cancellationToken); } public async Task> GetInstancesFilteredAsync( int? siteId = null, int? templateId = null, string? searchTerm = null, CancellationToken cancellationToken = default) { var query = _context.Instances.AsNoTracking().AsQueryable(); if (siteId.HasValue) query = query.Where(i => i.SiteId == siteId.Value); if (templateId.HasValue) query = query.Where(i => i.TemplateId == templateId.Value); if (!string.IsNullOrWhiteSpace(searchTerm)) query = query.Where(i => i.UniqueName.Contains(searchTerm)); return await query .OrderBy(i => i.UniqueName) .ToListAsync(cancellationToken); } public async Task> GetRecentDeploymentsAsync(int count, CancellationToken cancellationToken = default) { return await _context.DeploymentRecords .AsNoTracking() .OrderByDescending(d => d.DeployedAt) .Take(count) .ToListAsync(cancellationToken); } public async Task> GetAreaTreeBySiteIdAsync(int siteId, CancellationToken cancellationToken = default) { return await _context.Areas .AsNoTracking() .Where(a => a.SiteId == siteId) .Include(a => a.Children) .OrderBy(a => a.Name) .ToListAsync(cancellationToken); } public async Task<(IReadOnlyList Entries, int TotalCount)> GetAuditLogEntriesAsync( string? user = null, string? entityType = null, string? action = null, DateTimeOffset? from = null, DateTimeOffset? to = null, string? entityId = null, string? entityName = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) { var query = _context.AuditLogEntries.AsNoTracking().AsQueryable(); if (!string.IsNullOrWhiteSpace(user)) query = query.Where(a => a.User == user); if (!string.IsNullOrWhiteSpace(entityType)) query = query.Where(a => a.EntityType == entityType); if (!string.IsNullOrWhiteSpace(action)) query = query.Where(a => a.Action == action); if (from.HasValue) query = query.Where(a => a.Timestamp >= from.Value); if (to.HasValue) query = query.Where(a => a.Timestamp <= to.Value); if (!string.IsNullOrWhiteSpace(entityId)) query = query.Where(a => a.EntityId == entityId); if (!string.IsNullOrWhiteSpace(entityName)) query = query.Where(a => a.EntityName.Contains(entityName)); var totalCount = await query.CountAsync(cancellationToken); var entries = await query .OrderByDescending(a => a.Timestamp) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(cancellationToken); return (entries, totalCount); } public async Task SaveChangesAsync(CancellationToken cancellationToken = default) { return await _context.SaveChangesAsync(cancellationToken); } }