#!/usr/bin/ruby

OPTIONS = ['1 require', '2 not-mandatory', '3 maintainers-choice', '4 no-gr', '5 fd']

votes = {}

File.open('tally.txt').each_line do |line|
  next unless line.start_with?('V: ')
  _, vote, login, _ = line.split(/\s+/, 4)
  positions = vote.split(//).zip(OPTIONS)
  positions = positions.group_by { |p| p[0] }
  votes[login] = []
  positions.keys.sort_by! { |p| p[0] == '-' ? OPTIONS.length + 1 : p[0].to_i }.each do |key|
    votes[login] << positions[key].map { |p| p[1] }
  end
end

votes.each_pair do |login, vote|
  printf "%-35s %s\n", vote.map { |rank| "%5s" % rank.map { |s| s[0] == '5' ? '/' : s[0] }.join }.join(' '), login
end

# Are options 2 and 3 always close?
close = []
votes.each_pair do |login, vote|
  rest = vote.drop_while { |rank|
    !rank.include?('2 not-mandatory') && !rank.include?('3 maintainers-choice')
  }
  if (rest[0].include?('2 not-mandatory') && rest[0].include?('3 maintainers-choice')) ||
     (rest[1].include?('2 not-mandatory') || rest[1].include?('3 maintainers-choice'))
    close << login
  end
end
# => for 322 voters that's the case

# first choices
options = {}
votes.each_pair do |login, vote|
  vote[0].each do |option|
    options[option] ||= 0
    options[option] += 1
  end
end
# => 4 no-gr                253
#    1 require              119
#    2 not-mandatory         65
#    3 maintainers-choice    60
#    5 fd                    12

# I really don't want any further discussion
voters = []
votes.each_pair do |login, vote|
  voters << login if vote.last == ['5 fd']
end
# => 108

# The GR was needed (fd not as first choice but ranked above no-gr)
voters = []
votes.each_pair do |login, vote|
  next if vote[0].include?('5 fd')
  rest = vote.drop_while { |rank| !rank.include?('5 fd') }
  rest.shift
  voters << login if rest.drop_while { |rank| !rank.include?('4 no-gr') }.length > 0
end
# => 86

# no-gr > fd > …
voters = []
votes.each_pair do |login, vote|
  voters << login if vote[0] == ['4 no-gr'] && vote[1] && vote[1].include?('5 fd')
end
# => 50

# require > fd > …
voters = []
votes.each_pair do |login, vote|
  voters << login if vote[0] == ['1 require'] && vote[1] && vote[1].include?('5 fd')
end
# => 30
