#! /usr/bin/awk -f

##
##
## I'm not super happy with how this code looks.  Rest assured, though,
## the C version would look far, far worse.
##
##

function qsort(A, left, right,   i, last) {
    if (left >= right)
        return
    swap(A, left, left+int((right-left+1)*rand()))
    last = left
    for (i = left+1; i <= right; i++)
        if (A[i] < A[left])
            swap(A, ++last, i)
    swap(A, left, last)
    qsort(A, left, last-1)
    qsort(A, last+1, right)
}
function swap(A, i, j,   t) {
    t = A[i]; A[i] = A[j]; A[j] = t
}

function escape(s) {
    gsub("&", "&amp;", s)
    gsub("<", "&lt;", s)
    gsub(">", "&gt;", s)
    return s
}

function head() {
    print "<!DOCTYPE html>"
    print "<html><head><title>Project 2 Scoreboard</title>"
    print "<meta http-equiv=\"refresh\" content=\"60\">"
    print "<style>"
    print "html {background: black url(\"p2inv.png\") no-repeat top center; background-size: contain; min-height: 100%; color: white;}"
    print "body {background: black; opacity: 0.92; margin: 0;}"
    print "p {margin: 0;}"
    print "span {display: inline-block; margin: 0; border: 0;}"
    print ".cat0 {background-color: #a6cee3; color: black;}"
    print ".cat1 {background-color: #1f78b4;}"
    print ".cat2 {background-color: #b2df8a; color: black;}"
    print ".cat3 {background-color: #33a02c;}"
    print ".cat4 {background-color: #fb9a99;}"
    print ".cat5 {background-color: #e31a1c;}"
    print ".cat6 {background-color: #fdbf6f;}"
    print ".cat7 {background-color: #ff7f00;}"
    print ".cat8 {background-color: #cab2d6;}"

    print ".name {position: absolute; right: 10px;}"
    print "#scores p {margin: 0; padding: 0; border: thin solid #222; opacity: 0.92;}"
    print "#scores p:hover {border: thin solid yellow;}"
    print "</style>"
    print "</head><body>"
    print "<div id=\"scores\">"
}

function foot() {


    print "    </div>"
    print "    <pre style=\"position: fixed; bottom: 0; left: 20%; font-size: 250%;"
    print "    opacity: 0.8; background-color: black\">"
    print "Project 2<br>"
    print "<p>A CTF for people with limited time/patience/self-confidence.</p>"
    print "<p>Plug in ethernet at this table, download puzzles, go think.</p>"
    print "<p>http://10.0.0.2/</p>"
    print "<p>Use the terminal to claim points when you've figured something out.</p>"
    print "    </pre>"
    print "  </body>"
    print "</body></html>"
}

BEGIN {
    base = ENVIRON["CTF_BASE"]
    if (! base) {
        base = "/var/lib/ctf"
    }

    head()
}

# MAINLOOP
{
    time = $1
    hash = $2
    cat = $3
    points = int($4)

    # Build a list of team names
    if (! (hash in team_names)) {
        fn = sprintf("%s/teams/names/%s", base, hash)
        getline team_names[hash] < fn
        close(fn)
    }

    # Total points possible so far in this category
    if (! ((cat, points) in cat_pointval)) {
        cat_total[cat] += points
        cat_pointval[cat, points] = 1
    }

    # Enumerate categories
    if (! (cat in seen_cats)) {
        seen_cats[cat] = 1
        categories[ncats++] = cat
    }

    # Points this team has in this category
    cat_points[hash, cat] += points
}

END {
    # Adjust per-category points to a per-category percentage complete
    for (hash in team_names) {
        for (cat in cat_total) {
            cat_score[hash, cat] = cat_points[hash, cat] / cat_total[cat]
            total_score[hash] += cat_score[hash, cat]
        }
        scores[nteams++] = total_score[hash]
        if (total_score[hash] > max_score) {
            max_score = total_score[hash]
        }
    }

    # Sort scores
    qsort(scores, 0, nteams-1)

    print "<p>"
    for (ncat = 0; ncat < ncats; ncat += 1) {
        printf("<span class=\"cat%d\">%s</span>\n", ncat, categories[ncat]);
    }
    print "</p>"

    for (i = nteams-1; i >= 0; i -= 1) {
        score = scores[i];
        if (score == scores[i-1]) continue;         # Skip duplicates

        for (hash in team_names) {
            if (total_score[hash] != score) {
                continue;
            }

            name = escape(team_names[hash])
            print "<p>"
            printf("<span class=\"name\">%s</span>\n", name)

            for (ncat = 0; ncat < ncats; ncat += 1) {
                cat = categories[ncat];
                points = cat_points[hash, cat];

                if (cat_points[hash, cat] > 0) {
                    width = cat_score[hash, cat] / max_score * 90 
                    printf("<!-- %s %s %s -->", cat, points, name)
                    printf("<span class=\"cat%d\" style=\"width: %.2f%%;\">%d</span>", 
                            ncat, width, cat_points[hash, cat])
                }
            }
            print "</p>"
        }
    }

    foot()
}