public async Task <IActionResult> UpdateJudging(
            [FromRoute] string hostname,
            [FromRoute] int judgingId,
            [FromForm] UpdateJudgingModel model)
        {
            var host = await Judgehosts.FindAsync(hostname);

            // Unknown or inactive judgehost requested
            if (host is null)
            {
                return(Empty());
            }
            await Judgehosts.NotifyPollAsync(host);

            var(judging, pid, cid, uid, time) = await Judgings.FindAsync(judgingId);

            if (judging is null)
            {
                return(BadRequest());
            }
            judging.CompileError = model.output_compile ?? "";

            if (model.compile_success != 1)
            {
                judging.Status   = Verdict.CompileError;
                judging.StopTime = DateTimeOffset.Now;
                await FinishJudging(judging, cid, pid, uid, time);
            }
            else
            {
                await Judgings.UpdateAsync(judging);
            }

            return(Ok());
        }
        /// <summary>
        /// Finish the judging pipe, persist into database,
        /// create the events and notify scoreboard.
        /// </summary>
        private async Task FinishJudging(Judging j, int?cid, int pid, int uid, DateTimeOffset subtime)
        {
            if (cid == 0)
            {
                cid = null;
            }
            await Judgings.UpdateAsync(j);

            await HttpContext.AuditAsync(
                AuditlogType.Judging, cid, j.Server,
                "judged", $"{j.JudgingId}", $"{j.Status}");

            if (cid.HasValue && j.Active)
            {
                await HttpContext.RequestServices
                .GetRequiredService <MediatR.IMediator>()
                .JudgingFinished(cid.Value, subtime, pid, uid, j);
            }

            if (j.Active)
            {
                await HttpContext.RequestServices
                .GetRequiredService <ISubmissionStore>()
                .UpdateStatisticsAsync(cid ?? 0, uid, pid, j.Status == Verdict.Accepted);
            }

            Telemetry.TrackDependency(
                dependencyTypeName: "JudgeHost",
                dependencyName: j.Server,
                data: $"j{j.JudgingId} judged " + j.Status,
                startTime: j.StartTime ?? DateTimeOffset.Now,
                duration: (j.StopTime - j.StartTime) ?? TimeSpan.Zero,
                success: j.Status != Verdict.UndefinedError);
        }
        /// <summary>
        /// The judging meet an internal error, require a rejudging.
        /// </summary>
        private async Task ReturnToQueue(Judging j, int?cid, int pid, int uid, DateTimeOffset subtime)
        {
            await Judgings.CreateAsync(new Judging
            {
                Active            = j.Active,
                Status            = Verdict.Pending,
                FullTest          = j.FullTest,
                RejudgeId         = j.RejudgeId,
                PreviousJudgingId = j.PreviousJudgingId,
                SubmissionId      = j.SubmissionId,
            });

            j.Active            = false;
            j.Status            = Verdict.UndefinedError;
            j.RejudgeId         = null;
            j.PreviousJudgingId = null;
            if (!j.StopTime.HasValue)
            {
                j.StopTime = DateTimeOffset.Now;
            }

            if (cid == 0)
            {
                cid = null;
            }
            await FinishJudging(j, cid, pid, uid, subtime);
        }
        public async Task <ActionResult <List <UnfinishedJudging> > > OnPost(
            [FromForm, Required] string hostname)
        {
            var item = await Judgehosts.FindAsync(hostname);

            if (item is null)
            {
                item = await Judgehosts.CreateAsync(new JudgeHost
                {
                    ServerName = hostname,
                    PollTime   = DateTimeOffset.Now,
                    Active     = true
                });

                await HttpContext.AuditAsync(
                    "registered", hostname,
                    $"on {HttpContext.Connection.RemoteIpAddress}");

                Telemetry.TrackDependency(
                    dependencyTypeName: "JudgeHost",
                    dependencyName: item.ServerName,
                    data: "registed",
                    startTime: item.PollTime,
                    duration: TimeSpan.Zero,
                    success: true);

                return(new List <UnfinishedJudging>());
            }
            else
            {
                await Judgehosts.NotifyPollAsync(item);

                var oldJudgings = await Judgings.ListAsync(
                    predicate : j => j.Server == item.ServerName && j.Status == Verdict.Running,
                    selector : j => new { j, j.s.ContestId, j.s.Author, j.s.ProblemId, j.s.Time },
                    topCount : 10000);

                foreach (var sg in oldJudgings)
                {
                    await ReturnToQueue(sg.j, sg.ContestId, sg.ProblemId, sg.Author, sg.Time);
                }

                return(oldJudgings
                       .Select(s => new UnfinishedJudging
                {
                    judgingid = s.j.JudgingId,
                    submitid = s.j.SubmissionId,
                    cid = s.ContestId
                })
                       .ToList());
            }
        }
        public async Task <ActionResult <int> > InternalError(
            [FromForm] InternalErrorModel model,
            [FromServices] IInternalErrorStore store,
            [FromServices] ILanguageStore langs,
            [FromServices] IProblemStore probs)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            var toDisable = model.disabled.AsJson <InternalErrorDisable>();
            var kind      = toDisable.kind;

            var ie = await store.CreateAsync(
                new InternalError
            {
                JudgehostLog = model.judgehostlog,
                JudgingId    = model.judgingid,
                ContestId    = model.cid,
                Description  = model.description,
                Disabled     = model.disabled,
                Status       = InternalErrorStatus.Open,
                Time         = DateTimeOffset.Now,
            });

            if (kind == "language")
            {
                var langid = toDisable.langid;
                await langs.ToggleJudgeAsync(langid, false);

                Telemetry.TrackDependency(
                    dependencyTypeName: "Language",
                    dependencyName: langid,
                    data: model.description,
                    startTime: DateTimeOffset.Now,
                    duration: TimeSpan.Zero,
                    success: false);
            }
            else if (kind == "judgehost")
            {
                var hostname = toDisable.hostname;
                await Judgehosts.ToggleAsync(hostname, false);

                Telemetry.TrackDependency(
                    dependencyTypeName: "JudgeHost",
                    dependencyName: hostname,
                    data: model.description,
                    startTime: DateTimeOffset.Now,
                    duration: TimeSpan.Zero,
                    success: false);
            }
            else if (kind == "problem")
            {
                var probid = toDisable.probid.Value;
                await probs.ToggleJudgeAsync(probid, false);

                Telemetry.TrackDependency(
                    dependencyTypeName: "Problem",
                    dependencyName: $"p{probid}",
                    data: model.description,
                    startTime: DateTimeOffset.Now,
                    duration: TimeSpan.Zero,
                    success: false);
            }
            else
            {
                Telemetry.TrackDependency(
                    dependencyTypeName: "Unresolved",
                    dependencyName: kind,
                    data: model.description,
                    startTime: DateTimeOffset.Now,
                    duration: TimeSpan.Zero,
                    success: false);
            }

            if (model.judgingid.HasValue)
            {
                var(j, pid, cid, uid, time) = await Judgings.FindAsync(model.judgingid.Value);
                await ReturnToQueue(j, cid, pid, uid, time);
            }

            await HttpContext.AuditAsync("added", $"{ie.ErrorId}", $"for {kind}");

            return(ie.ErrorId);
        }
        public async Task <IActionResult> AddJudgingRun(
            [FromRoute] string hostname,
            [FromRoute] int judgingId,
            [FromForm, ModelBinder(typeof(JudgingRunBinder))] List <JudgingRunModel> batch)
        {
            if (batch is null)
            {
                return(BadRequest());
            }

            var host = await Judgehosts.FindAsync(hostname);

            if (host is null)
            {
                return(BadRequest());              // Unknown or inactive judgehost requested
            }
            await Judgehosts.NotifyPollAsync(host);

            var(judging, pid, cid, uid, time) = await Judgings.FindAsync(judgingId);

            if (judging is null)
            {
                Logger.LogError("Unknown judging result.");
                return(BadRequest());
            }

            foreach (var run in batch)
            {
                var detail = await Judgings.CreateAsync(run.ParseInfo(judgingId, host.PollTime));

                if (run.output_error is null || run.output_run is null)
                {
                    continue;
                }
                try
                {
                    var stderr = Convert.FromBase64String(run.output_error);
                    var stdout = Convert.FromBase64String(run.output_run);
                    await Judgings.SetRunFileAsync(judgingId, detail.TestId, "out", stdout);

                    await Judgings.SetRunFileAsync(judgingId, detail.TestId, "err", stderr);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "An error occurred when saving OutputError and OutputRun for j{judgingId}", judgingId);
                }
            }

            // Check for the final status
            var countTc = await HttpContext.RequestServices
                          .GetRequiredService <ITestcaseStore>()
                          .CountAsync(pid);

            var verdict = await Judgings.SummarizeAsync(judging);

            // testId for score, testcaseId for count of tested cases

            bool anyRejected = !judging.FullTest && verdict.Status != Verdict.Accepted;
            bool fullTested  = verdict.TestcaseId >= countTc && countTc > 0;

            if (anyRejected || fullTested)
            {
                judging.ExecuteMemory = verdict.ExecuteMemory;
                judging.ExecuteTime   = verdict.ExecuteTime;
                judging.Status        = verdict.Status;
                judging.StopTime      = host.PollTime;
                judging.TotalScore    = verdict.TestId;
                await FinishJudging(judging, cid, pid, uid, time);
            }

            return(Ok());
        }
        public async Task <ActionResult <NextJudging> > NextJudging([FromRoute] string hostname)
        {
            var host = await Judgehosts.FindAsync(hostname);

            if (host is null)
            {
                return(Empty());              // Unknown or inactive judgehost requested
            }
            await Judgehosts.NotifyPollAsync(host);

            if (!host.Active)
            {
                return(Empty());
            }

            var r = new
            {
                judging = (Judging)null,
                lang    = (Language)null,
                prob    = (Problem)null,
                cid     = 0,
                teamid  = 0,
                rjid    = new int?(),
            };

            using (await Lock.LockAsync())
            {
                r = await Judgings.FindAsync(
                    predicate : j => j.Status == Verdict.Pending &&
                    j.s.l.AllowJudge &&
                    j.s.p.AllowJudge &&
                    !j.s.Ignored,
                    selector : j => new
                {
                    judging = j,
                    lang    = j.s.l,
                    prob    = j.s.p,
                    cid     = j.s.ContestId,
                    teamid  = j.s.Author,
                    rjid    = j.s.RejudgeId
                });

                if (r is null)
                {
                    return(Empty());
                }

                var judging = r.judging;
                judging.Status    = Verdict.Running;
                judging.Server    = host.ServerName;
                judging.StartTime = DateTimeOffset.Now;
                await Judgings.UpdateAsync(judging);

                //if (cid != 0)
                //{
                //    var cts = new Data.Api.ContestJudgement(
                //        judging, next.StartTime ?? DateTimeOffset.Now);
                //    DbContext.Events.Add(cts.ToEvent("create", cid));
                //}
            }

            var toFindMd5 = new[] { r.prob.RunScript, r.prob.CompareScript, r.lang.CompileScript };
            var md5s      = await HttpContext.RequestServices
                            .GetRequiredService <IExecutableStore>()
                            .ListMd5Async(toFindMd5);

            var tcss = await HttpContext.RequestServices
                       .GetRequiredService <ITestcaseStore>()
                       .ListAsync(r.prob.ProblemId);

            return(new NextJudging
            {
                submitid = r.judging.SubmissionId,
                cid = r.cid,
                teamid = r.teamid,
                probid = r.prob.ProblemId,
                langid = r.lang.Id,
                rejudgingid = r.rjid,
                entry_point = null,
                origsubmitid = null,
                maxruntime = r.prob.TimeLimit * r.lang.TimeFactor / 1000.0,         // as seconds
                memlimit = r.prob.MemoryLimit + (r.lang.Id == "java" ? 131072 : 0), // as kb, java more 128M
                outputlimit = r.prob.OutputLimit,                                   // KB
                run = r.prob.RunScript,
                compare = r.prob.CompareScript,
                compare_args = r.prob.ComapreArguments,
                compile_script = r.lang.CompileScript,
                combined_run_compare = r.prob.CombinedRunCompare,
                compare_md5sum = md5s[r.prob.CompareScript],
                run_md5sum = md5s[r.prob.RunScript],
                compile_script_md5sum = md5s[r.lang.CompileScript],
                judgingid = r.judging.JudgingId,
                full_judge = r.judging.FullTest && (r.cid == 0 || r.judging.RejudgeId != null),
                testcases = tcss.ToDictionary(t => $"{t.Rank}", t => new TestcaseToJudge(t))
            });
        }