/*
         * private static string[] _columns = {
         *  "AimSeqNumber",
         *  "ErrorString",
         *  "Severity",
         *  "FieldValues",
         *  "LearnRefNumber",
         *  "RuleId"
         * };
         *
         * private static string reportCommand = "select * from [Report].[ValidationError] where Severity {0} 'E'";
         */

        /// <summary>
        /// Runs the report.
        /// </summary>
        /// <param name="usingSession">using session.</param>
        /// <param name="inContext">in context.</param>
        public void RunReport(IContainSessionConfiguration usingSession, IContainSessionContext inContext)
        {
            using (Timing.BeginScope($"Reporting"))
            {
                Emitter.Publish("Generating reports");

                Emitter.Publish(Indentation.FirstLevel, "***** Reports are not currently implemented *****");

                // TODO: fix report builders...

                //var sqlConn = new SqlConnection(_con);

                //var errorReport = _report.Create(_columns, new SqlCommand(string.Format(reportCommand, "="), sqlConn));
                //var warningReport = _report.Create(_columns, new SqlCommand(string.Format(reportCommand, "<>"), sqlConn));

                //if (!Directory.Exists(Path.Combine(AppContext.BaseDirectory, "Reports")))
                //{
                //    Directory.CreateDirectory(Path.Combine(AppContext.BaseDirectory, "Reports"));
                //}

                //Parallel.Invoke(
                //    () => File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "Reports", "Errors.csv"), errorReport),
                //    () => File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "Reports", "Warnings.csv"), warningReport));

                Emitter.Publish(Indentation.FirstLevel, CommonLocalised.Completed);
            }
        }
 /// <summary>
 /// Starts the log.
 /// </summary>
 /// <param name="usingSession">using session.</param>
 /// <param name="andProvider">and provider.</param>
 public void StartLog(IContainSessionConfiguration usingSession, ILearningProvider andProvider, IContainSessionContext inContext)
 {
     Emitter.Publish($"Running job for provider '{andProvider.ID}'");
     Emitter.Publish($"The application is running in '{inContext.RunMode}' mode");
     Emitter.Publish($"The '{usingSession.InputDataSource.OperatingYear.AsString()}' ruleset will be used");
     Emitter.Publish($"This provider has {andProvider.LearnerCount} learners");
     Emitter.Publish(CommonLocalised.LineDivider);
 }
        /// <summary>
        /// Prepares the run.
        /// </summary>
        /// <param name="usingSession">using session.</param>
        /// <param name="inContext">in context.</param>
        /// <param name="forThisProvider">For this provider.</param>
        public void PrepareRun(IContainSessionConfiguration usingSession, IContainSessionContext inContext, int forThisProvider, bool initalise)
        {
            using (Timing.BeginScope($"Preparation"))
            {
                var _inYear = usingSession.InputDataSource.OperatingYear;

                ProcessingDataStore.Prepare(inContext, forThisProvider, _inYear, initalise);
                //SourceData.Clone(inContext, forThisProvider, _inYear);
            }
        }
        /// <summary>
        /// Completes the run.
        /// </summary>
        /// <param name="usingSession">using session.</param>
        /// <param name="inContext">in context.</param>
        /// <param name="forThisProvider">for this provider.</param>
        public void CompleteRun(IContainSessionConfiguration usingSession, IContainSessionContext inContext, int forThisProvider)
        {
            using (Timing.BeginScope($"Completion"))
            {
                var _inYear = usingSession.InputDataSource.OperatingYear;

                ResultsDataStore.Prepare(inContext, forThisProvider, _inYear, forceCreation: true);
                // TODO: add back in so we dont lose sight
                //Results.Clone(inContext, forThisProvider, _inYear);
            }
        }
 /// <summary>
 /// Requires return period.
 /// </summary>
 /// <param name="usingSession">using session.</param>
 /// <param name="inContext">in context.</param>
 /// <returns>true, if AEC included in run and no return period set</returns>
 public bool RequiresReturnPeriod(IContainSessionConfiguration usingSession, IContainSessionContext inContext) =>
 It.IsInRange(inContext.ReturnPeriod, ReturnPeriod.None) &&
 usingSession.RulesToRun.Any(x => x.ShortName == "AEC");
        /// <summary>
        /// Runs the rules.
        /// </summary>
        /// <param name="usingSession">using session.</param>
        /// <param name="inContext">in context.</param>
        /// <returns>the currently running task</returns>
        public void RunRules(IContainSessionConfiguration usingSession, IContainSessionContext inContext, bool saveResults)
        {
            using (Timing.BeginScope("This processing run"))
            {
                if (RequiresReturnPeriod(usingSession, inContext))
                {
                    throw new Exception("Please pick a return period if you wish to run the AEC rulebase");
                }

                Emitter.Publish("Commencing run...");

                var providers = usingSession.InputDataSource.Providers
                                .Where(x => x.IsSelectedForProcessing);

                Monitor.SetProviderCount(providers.Count());

                //INTPUT FOR THE REFERECE DATA
                PostValidation.TransformInput(inContext, usingSession.InputDataSource.OperatingYear);


                providers.ForEach(usingProvider =>
                {
                    Monitor.IncrementPosition();
                    Monitor.SetLearnerCounts(0, usingProvider.LearnerCount, 0);

                    var fileName   = $"{usingProvider.ID}_{DateTime.Now:yyyyMMdd-HHmmss}.log";
                    var firstInRun = Monitor.ProviderPosition == 1;

                    using (Logging.BeginScope(fileName, firstInRun))
                    {
                        using (Timing.BeginScope($"This provider '{usingProvider.ID}'", x => GetProcessingAverage(usingProvider.LearnerCount, x)))
                        {
                            // start the log
                            StartLog(usingSession, usingProvider, inContext);
                            // writes current UKPRN
                            WriteOutUKPRN(usingProvider.ID, inContext);
                            // build
                            PrepareRun(usingSession, inContext, usingProvider.ID, firstInRun);
                            // validate
                            RunRulebaseSubset(TypeOfRulebaseOperation.Validation, usingSession.RulesToRun, inContext, usingProvider.ID);
                            // transform
                            TransformInput(inContext, usingSession.InputDataSource.OperatingYear, usingProvider);
                            // calculate
                            RunRulebaseSubset(TypeOfRulebaseOperation.Calculation, usingSession.RulesToRun, inContext, usingProvider.ID);
                            // complete
                            if (saveResults == true)
                            {
                                CompleteRun(usingSession, inContext, usingProvider.ID);
                            }
                            // report
                            RunReport(usingSession, inContext);
                        }
                    }
                });

                // reset the badges
                Monitor.IncrementPosition();
                Monitor.SetLearnerCounts(0, 0, 0);
                Monitor.SetCaseCount(null, 0);
            }
        }
 /// <summary>
 /// Runs...
 /// </summary>
 /// <param name="usingSession">using session.</param>
 /// <param name="inContext">in context.</param>
 /// <returns>
 /// the currently running task
 /// </returns>
 public async Task Run(IContainSessionConfiguration usingSession, IContainSessionContext inContext, bool saveResults)
 {
     await Handler.RunOperation <Localised>(() => RunRules(usingSession, inContext, saveResults));
 }