using Hcs.WebApp.Data.Hcs; using Hcs.WebApp.Services; using Hcs.WebApp.Utils; namespace Hcs.WebApp.BackgroundServices.CampaignManagers { public abstract class ManagerBase( IServiceScopeFactory scopeFactory, OperationExecutionState operationExecutionState, ResultGetState resultGetState, DataParsingState dataParsingState, Campaign campaign) : IManager { protected readonly IServiceScope scope = scopeFactory.CreateScope(); protected readonly OperationExecutionState operationExecutionState = operationExecutionState; protected readonly ResultGetState resultGetState = resultGetState; protected readonly DataParsingState dataParsingState = dataParsingState; protected readonly Campaign campaign = campaign; private HeadquartersService? headquartersService; public Campaign Campaign => campaign; public IManager.ManagerState State { get; protected set; } protected HeadquartersService HeadquartersService => headquartersService ??= scope.ServiceProvider.GetRequiredService(); protected abstract int StepCount { get; } public event IManager.CampaignStarted OnCampaignStarted; public event IManager.CampaignProgressStep OnCampaignProgressStep; public event IManager.CampaignEnded OnCampaignEnded; public abstract Task ProcessAsync(); public async Task EndWithFailAsync(Exception e) { var endedAt = DateTime.Now; var failureReason = e.CombineMessages(); await HeadquartersService.SetCampaignEndedWithFailAsync(campaign.Id, endedAt, failureReason); State = IManager.ManagerState.Ended; InvokeOnCampaignEnded(endedAt, failureReason); } protected void InvokeOnCampaignStarted(DateTime startedAt) { OnCampaignStarted?.Invoke(campaign.Id, startedAt); } protected async Task ProgressStepAsync(int step) { using var context = HeadquartersService.GetNewContext(); await ProgressStepAsync(context, step); } protected void InvokeOnCampaignEnded(DateTime endedAt, string failureReason) { OnCampaignEnded?.Invoke(campaign.Id, campaign.Type, endedAt, failureReason); } protected async Task ProgressStepAsync(HcsDbContext context, int step) { campaign.Step = step; campaign.Progress = Convert.ToInt32(((step + 1) / (float)StepCount * 100)); await HeadquartersService.UpdateCampaignStepAndProgressAsync(context, campaign); OnCampaignProgressStep?.Invoke(campaign.Id, campaign.Step, campaign.Progress); } } }