#!/usr/bin/env python3

from os import environ
ipc_path =  "{}/node/geth.ipc".format(environ.get('BFANETWORKDIR', "~/bfa/network"))
rpc_port = 8545
rpc_host = "localhost"
import requests
from web3 import Web3, IPCProvider
from web3.middleware import geth_poa_middleware
from itertools import groupby
import argparse


def getSigners():
    session = requests.Session()
    payload = {"jsonrpc":"2.0", "method":'clique_getSigners',"params":[],"id":1}
    headers = {'Content-type':'application/json'} 
    response = session.post(
        "http://{}:{}".format(rpc_host,rpc_port),
        json=payload,
        headers=headers)
    return response.json()['result']

def getVotes():
    session = requests.Session()
    payload = {"jsonrpc":"2.0", "method":'clique_getSnapshot',"params":[],"id":1}
    headers = {'Content-type':'application/json'} 
    response = session.post(
        "http://{}:{}".format(rpc_host,rpc_port),
        json=payload,
        headers=headers)
    votes = {}
    for vote in response.json()['result']['votes']:
        if vote['address'] not in votes:
            votes[vote['address']] = {signer:"" for signer in getSigners()}
        votes[vote['address']][vote['signer']] = vote['authorize']
    return votes



if __name__ == "__main__":

    parser = argparse.ArgumentParser(description=
        """Muestra el estado de una votaciĆ³n""")
    parser.add_argument("--ipc-path", help ="Path del archivo geth.ipc. Default: {}".format(ipc_path))
    parser.add_argument("--rpc-port", help ="Puerto RPC. Default: {}".format(rpc_port),type=int)
    args = parser.parse_args()
    if args.ipc_path:
        ipc_path = args.ipc_path
    if args.rpc_port:
        rpc_port = args.rpc_port
    w3 = Web3(Web3.IPCProvider(ipc_path))
    w3.middleware_stack.inject(geth_poa_middleware, layer=0)
    for proposal, votes in sorted(getVotes().items()):
        print("Propuesta: {}".format(proposal))
        for voter, vote in sorted(votes.items()):
            print("\t{}: {}".format(voter,vote))
        tally = { k:len(list(v)) for (k,v) in groupby(sorted(map(str,votes.values())))}
        print("A favor: {}, en contra: {}, no votaron: {}\n".format(
            tally.get("True",0), 
            tally.get("False",0), 
            tally.get("",0)))