using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; using AnalyticsDAL.CustomCode.DataSource; using AnalyticsDAL.DTO.AnalysisAggregation.V1; using AnalyticsDAL.DTO.BICatalog; using AnalyticsDAL.DTO.DataSource; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Report; using GB5Shared.ExcelExport; namespace AnalyticsDAL.CustomCode.ApiDataset { public class ApiDatasetDAL : IApiDatasetDAL { private readonly IDataSourceDAL _dataSourceDAL; private readonly IExcelExport _excelExport; public ApiDatasetDAL(IDataSourceDAL dataSourceDAL, IExcelExport excelExport) { _dataSourceDAL = dataSourceDAL; _excelExport = excelExport; } public async Task>> FetchRowsAsync( DatasetResolutionDTO resolution, AnalysisQueryDefinition definition, LoginDTO login, CancellationToken ct) { if (resolution.DataSourceId is not int dataSourceId) throw new InvalidOperationException("ApiService dataset resolution is missing DataSourceId."); if (string.IsNullOrWhiteSpace(resolution.ResourcePath)) throw new InvalidOperationException("ApiService dataset resolution is missing ResourcePath."); var json = await _dataSourceDAL.GetDataSource(dataSourceId, login, ct).ConfigureAwait(false); var dataSource = JsonSerializer.Deserialize(json) ?? throw new InvalidOperationException($"DataSource {dataSourceId} could not be resolved."); if (dataSource.DataSourceType != 4) // 4 = RestAPI, per MDATASOURCE.DATASOURCETYPE throw new InvalidOperationException( $"DataSource {dataSourceId} is not a RestAPI-type source (DataSourceType={dataSource.DataSourceType})."); // HOSTNAME holds the API base URL for RestAPI-type sources (a convention, not a // dedicated column — MDATASOURCE has no URL-specific field; see the plan's // "to verify before implementing" note for MDATASOURCE's actual column list). var baseUrl = dataSource.HostName?.TrimEnd('/') ?? string.Empty; var resourcePath = resolution.ResourcePath!.TrimStart('/'); var fullUri = string.IsNullOrEmpty(baseUrl) ? resolution.ResourcePath! : $"{baseUrl}/{resourcePath}"; var reportCallingDTO = new ReportCallingDTO { ReportUri = fullUri, CriteriaDTO = BuildCriteriaDTO(definition) }; var rows = new List>(); await foreach (var row in _excelExport.ReportURICalling(reportCallingDTO, login, ct).WithCancellation(ct).ConfigureAwait(false)) rows.Add(row); return rows; } private static CriteriaDTO BuildCriteriaDTO(AnalysisQueryDefinition definition) { var attributeCriteria = definition.Filters.Select(f => new AttributesCriteriaDTO { FieldName = f.Field, OperationType = f.Operator, FieldValue = f.Values.Length > 0 ? f.Values[0] : null, InArray = f.Values, JoinType = CriteriaDTO.AttributeJoinOperationType.And }).ToList(); return new CriteriaDTO { SectionCriteriaList = new List { new SectionCriteriaDTO { SectionId = 0, OperationType = CriteriaDTO.SectionOperationType.And, AttributesCriteriaList = attributeCriteria } } }; } } }