aboutsummaryrefslogtreecommitdiff
path: root/Pages/JobCounter/Index.cshtml.cs
blob: cec36fa527ed799f7d67093a4432a241383600a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Text.RegularExpressions;

namespace PagerParser.Pages;

public class IndexModel : PageModel {
    private readonly PagerContext            db;
    private readonly JobCounterConfiguration config = new();

    private string pageDestination;

    public IndexModel(PagerContext db, IConfiguration config) {
        this.db = db;

        config.Bind("PagerParser:JobCounter", this.config);
    }

    public int RefreshInterval => config.RefreshInterval ?? 0;
    public string MessageFilter =>
        $"^@@ALERT.*\\[{Regex.Escape(pageDestination)}\\]$";

    public int TotalJobs {
        get {
            // Attempt to calculate the number of jobs attended based on the
            // number of distinct FIRS report numbers for successfully-parsed
            // pager messages plus the number of unparsed, but matched alert
            // messages. We attempt to scale the number of unparsed messages
            // based on the ratio of duplicate FIRS report numbers that appear
            // in the parsed messages, to best predict and compensate for
            // re-paged jobs, before they are added to the tally.

            // TODO: filter parsed messages based on page destination

            var date = new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            var matchedMessages = db.PagerMessages
                .Where(m => m.Timestamp >= date)
                .Where(m => Regex.IsMatch(m.Message, MessageFilter));
            var parsedMessages = matchedMessages
                .Where(m => m.ParsedMessage != null)
                .Select(m => m.ParsedMessage!);

            var matchedMessageCount = matchedMessages.Count();
            var parsedMessageCount  = parsedMessages.Count();

            var jobNumberCount = parsedMessages
                .Select(pm => pm.FirecomJobNo)
                .Distinct()
                .Count();

            double uniqueJobRate =
                (double) jobNumberCount / (double) parsedMessageCount;

            // Scale the number of unparsed messages and add
            // them to the tally of distinct FIRS job numbers
            jobNumberCount +=
                (int) Math.Round((matchedMessageCount - parsedMessageCount) * uniqueJobRate);

            // Apply the manually-entered offset if needed
            if(config.CountOffsets.TryGetValue(pageDestination, out int offset))
                jobNumberCount += offset;

            return jobNumberCount;
        }
    }

    public override void OnPageHandlerExecuting(PageHandlerExecutingContext context) =>
        pageDestination = (string) RouteData.Values["PageDestination"]!;

    private record JobCounterConfiguration {
        public int?                    RefreshInterval { get; set; } = 300;
        public Dictionary<string, int> CountOffsets    { get; set; } = new();
    }
}