#!/usr/bin/env python

import argparse
import sys
import os
import shutil
import glob

sys.path.append(os.path.join(os.path.dirname(__file__), "../vtr_flow/scripts/partitioning"))

import hypergraph_to_graph
import update_net_file
import compute_placement_compliance
import compute_hyperedge_cut
import generate_logical_block_placement_constraints

VPR_BIN=os.path.join(os.path.dirname(__file__), "vpr")
METIS_BIN=os.path.join(os.path.dirname(__file__), "gpmetis")
ROUTE_LOG_FILE='vpr_jvds.route.out'
PACK_LOG_FILE='vpr_jvds.pack.out'

LOGICAL_HYPERGRAPH_FILE='logical_hypergraph.txt'
LOGICAL_BLOCKS_FILE='logical_blocks.txt'

CLB_HYPERGRAPH_FILE='clb_hypergraph.txt'
CLB_BLOCKS_FILE='clb_blocks.txt'

PLACEMENT_CONSTRAINTS_ONLY=False
PASS_CONSTRAINTS_TO_PLACER=True

def read_stage():
    stage = 0
    try:
        with open("stage.txt") as f:
            for line in f:
                line = line.strip()
                if len(line) > 0:
                    stage = int(line)
    except IOError:
        pass
    return stage

def write_stage(stage):
    with open("stage.txt", "w") as f:
        f.write("%d\n" % stage)

def main():
    parser = argparse.ArgumentParser(description='')
    parser.add_argument('--staged', dest='staged', action='store_true', default=False)
    parser.add_argument('--ub-factor', type=int, default=3)
    parser.add_argument('--graph-model', choices=['clique', 'star', 'none'], default='clique')
    parser.add_argument('--graph-edge-weight', choices=['1/f', '1/f2', '1'], default='1/f')
    # space out factor should be handled by vpr
    #parser.add_argument('--spaceout-factor', type=float, default=1.1)
    args, vpr_args_list = parser.parse_known_args()

    # look for the num_cuts argument to figure out the number of partitions
    num_cuts_pos = vpr_args_list.index('--num_cuts')
    assert(num_cuts_pos >= 0)
    num_cuts = int(vpr_args_list[num_cuts_pos+1])
    num_partitions = num_cuts+1

    # filter out any args that were meant for us
    #vpr_args_list = filter(is_vpr_arg, sys.argv[1:])
    vpr_args = " ".join(vpr_args_list)

    # run VPR --route
    if "--route" in sys.argv:
        vpr_cmd = "%s --net_file packed_partitioned.net %s" % (VPR_BIN, vpr_args)
        log = open(ROUTE_LOG_FILE, 'a')
        log.write(vpr_cmd + "\n")
        log.close()
        status = os.system(vpr_cmd)
        sys.exit(status)

    # remove --seed [digit] from args
    if "--seed" in vpr_args_list:
        seed_idx = vpr_args_list.index('--seed')
        # first pop removes --seed, second pop removes seed number
        vpr_args_list.pop(seed_idx)
        vpr_args_list.pop(seed_idx)
    vpr_pack_args = " ".join(vpr_args_list)

    if args.staged:
        stage = read_stage()
        print "read stage %s" % stage
    else:
        stage = -1

    # run VPR --pack
    vpr_cmd = "%s --pack --net_file packed.net %s" % (VPR_BIN, vpr_pack_args)
    if stage in [-1, 0]:
        log = open(PACK_LOG_FILE, 'a')
        log.write(vpr_cmd + "\n")
        log.close()
        status = os.system(vpr_cmd)
        if status != 0:
            sys.exit(status)

    if stage in [-1, 1]:
        if args.graph_model != "none":
            if PLACEMENT_CONSTRAINTS_ONLY:
                input_hypergraph = CLB_HYPERGRAPH_FILE
                input_blocks = CLB_BLOCKS_FILE
            else:
                input_hypergraph = LOGICAL_HYPERGRAPH_FILE
                input_blocks = LOGICAL_BLOCKS_FILE
            # convert hypergraph to graph
            hypergraph_to_graph.run(blocks_file=input_blocks, input_hypergraph=input_hypergraph, output_graph='justgraph.txt', graph_model=args.graph_model, graph_edge_weight=args.graph_edge_weight)

            # run metis
            status = os.system("%s -ufactor=%d justgraph.txt %d" % (METIS_BIN, args.ub_factor * 10, num_partitions))
            if status != 0:
                sys.exit(status)

            # get the hyperedge cut
            hec = compute_hyperedge_cut.run(input_hypergraph, 'justgraph.txt.part.%d' % num_partitions)
            with open('hyperedge_cut.txt', 'w') as f:
                f.write("%d\n" % hec)

            # get nx and ny
            nx = -1
            ny = -1
            with open('vpr_stdout.log') as f:
                for line in f:
                    if "mapped into" in line:
                        parts = line.split()
                        nx = int(parts[7])
                        ny = int(parts[9])
                        break
            assert(nx != -1)
            assert(ny != -1)

            if PLACEMENT_CONSTRAINTS_ONLY:
                # update net file with regions
                update_net_file.run(input_net_file='packed.net', output_net_file='packed_partitioned.net', partitions_file=('justgraph.txt.part.%d' % num_partitions), total_partitions=num_partitions, nx=nx, ny=ny, blocks=input_blocks)
            else:
                generate_logical_block_placement_constraints.run(output_partitions='placement_regions.txt', partitions_file=('justgraph.txt.part.%d' % num_partitions), total_partitions=num_partitions, nx=nx,ny=nx)
                # run the damn thing again, hoping it uses the new placement regions file
                status = os.system(vpr_cmd)
                if PASS_CONSTRAINTS_TO_PLACER:
                    shutil.copyfile('packed.net', 'packed_partitioned.net')
                else:
                    update_net_file.remove_regions('packed.net', 'packed_partitioned.net')
        else:
            shutil.copyfile('packed.net', 'packed_partitioned.net')

    if stage in [-1, 2]:
        status = os.system("%s --place --route --net_file packed_partitioned.net %s" % (VPR_BIN, vpr_args))
        if status != 0:
            sys.exit(status)

        # get the placement compliance
        place_file = glob.glob('*.place')[0]
        count_good, count_bad = compute_placement_compliance.run(place_file, 'packed_partitioned.net')
        with open('placement_compliance.txt', 'w') as f:
            f.write("%f\n" % (float(count_good)/float(count_good+count_bad)))

    if args.staged:
        # set stage for next run
        write_stage(stage + 1)

main()
