#!/usr/bin/python3

import argparse

import psycopg
import psycopg.rows

def get_args():
    ap = argparse.ArgumentParser()
    ap.add_argument("--reverse", action="store_true")
    ap.add_argument("meet", type=int)
    ap.add_argument("kind")

    args = ap.parse_args()
    return args

def get_ballots():
    db = psycopg.connect(dbname="meeat", user="www-meeat")

    csr = db.cursor(row_factory=psycopg.rows.namedtuple_row)

    kind = args.kind
    q = f"""
         select {kind}.*, bod, position,
         min(w) over(partition by bod order by position) as vote_w
         from {kind} join {kind}_vote on {kind}.id = {kind}_vote.{kind}
         where meet = %s
         order by bod, position
         """
    csr.execute(q, (args.meet,))

    last_bod = None
    ballots = []
    for r in csr:
        if r.bod != last_bod:
            ballot = []
            ballots.append(ballot)
            last_bod = r.bod
        ballot.append(r)
    return ballots

def dump_ballots(ballots):
    for ballot in ballots:
        print ("---")
        for r in ballot:
            print(r)

def runoff(ballots):
    count = {}
    candidates = {}
    for ballot in ballots:
        for r in ballot:
            count[r.id] = [0] * len(ballot)
            candidates[r.id] = r
    for ballot in ballots:
        weight = max(r.vote_w for r in ballot)
        for pos, r in enumerate(ballot):
            count[r.id][pos] += weight
    if args.reverse:
        result = sorted(count.keys(), key=lambda i: list(reversed(count[i])), reverse=True)
    else:
        result = sorted(count.keys(), key=lambda i: count[i])
    print("result of this round:")
    for r in result:
        print(r, count[r])
    print("striking", result[0])
    loser = candidates[result[0]]
    new_ballots = [
        [
            r for r in ballot if r.id != loser.id
        ] for ballot in ballots
    ]
    return loser, new_ballots

if __name__ == "__main__":
    args = get_args()

    ballots = get_ballots()

    result = []
    while max(len(b) for b in ballots):
        dump_ballots(ballots)
        loser, ballots = runoff(ballots)
        result.append(loser)
    result = reversed(result)
    print("final result")
    for r in result:
        print(r)