using System.Data; using AMREZ.EOP.Abstractions.Applications.Tenancy; using AMREZ.EOP.Abstractions.Applications.UseCases.Tenancy; using AMREZ.EOP.Abstractions.Infrastructures.Common; using AMREZ.EOP.Abstractions.Infrastructures.Repositories; using AMREZ.EOP.Contracts.DTOs.Tenancy.UpdateTenant; using Microsoft.AspNetCore.Http; namespace AMREZ.EOP.Application.UseCases.Tenancy; public sealed class UpdateTenantUseCase : IUpdateTenantUseCase { private readonly ITenantResolver _resolver; private readonly IHttpContextAccessor _http; private readonly IUnitOfWork _uow; private readonly ITenantRepository _repo; public UpdateTenantUseCase(ITenantResolver resolver, IHttpContextAccessor http, IUnitOfWork uow, ITenantRepository repo) { _resolver = resolver; _http = http; _uow = uow; _repo = repo; } public async Task ExecuteAsync(UpdateTenantRequest request, CancellationToken ct = default) { var http = _http.HttpContext ?? throw new InvalidOperationException("No HttpContext"); var key = (request?.TenantKey ?? string.Empty).Trim().ToLowerInvariant(); if (string.IsNullOrWhiteSpace(key)) return null; var ctx = _resolver.Resolve(http, hint: null); if (ctx is null) return null; await _uow.BeginAsync(ctx, IsolationLevel.ReadCommitted, ct); try { var current = await _repo.GetAsync(key, ct); if (current is null) { await _uow.RollbackAsync(ct); return null; } // 404 if (request!.IfUnmodifiedSince.HasValue && current.UpdatedAtUtc > request.IfUnmodifiedSince.Value) { await _uow.RollbackAsync(ct); return null; } // 412 current.Schema = request.Schema is null ? current.Schema : (string.IsNullOrWhiteSpace(request.Schema) ? null : request.Schema.Trim()); current.ConnectionString = request.ConnectionString is null ? current.ConnectionString : (string.IsNullOrWhiteSpace(request.ConnectionString) ? null : request.ConnectionString.Trim()); if (request.Mode.HasValue) current.Mode = request.Mode.Value; if (request.IsActive.HasValue) current.IsActive = request.IsActive.Value; current.UpdatedAtUtc = DateTimeOffset.UtcNow; var ok = await _repo.UpdateAsync(current, request.IfUnmodifiedSince, ct); if (!ok) { await _uow.RollbackAsync(ct); return null; } await _uow.CommitAsync(ct); return new UpdateTenantResponse(current.TenantKey, current.UpdatedAtUtc); } catch { await _uow.RollbackAsync(ct); throw; } } }