#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020  The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
from __future__ import print_function
import prjxray.db
import prjxray.lib
import argparse
import datetime
import progressbar
import multiprocessing
import pyjson5 as json5
import json
import sys
from prjxray import util


def full_wire_name(wire_in_grid):
    return '{}/{}'.format(wire_in_grid.tile, wire_in_grid.wire)


def make_connection(wires, connection):
    wire_a = full_wire_name(connection.wire_a)
    wire_b = full_wire_name(connection.wire_b)

    if wire_a not in wires:
        wires[wire_a] = set((wire_a, ))

    if wire_b not in wires:
        wires[wire_b] = set((wire_b, ))

    wire_a_set = wires[wire_a]
    wire_b_set = wires[wire_b]

    if wire_a_set is wire_b_set:
        return

    wire_a_set |= wire_b_set

    for wire in wire_a_set:
        wires[wire] = wire_a_set


def make_connections(db_root, part):
    db = prjxray.db.Database(db_root, part)
    c = db.connections()

    wires = {}
    for connection in c.get_connections():
        make_connection(wires, connection)

    nodes = {}

    for wire_node in wires.values():
        nodes[id(wire_node)] = wire_node

    return nodes.values()


def read_json5(fname):
    with open(fname, 'r') as f:
        return json5.load(f)


def main():
    parser = argparse.ArgumentParser(
        description="Tests database against raw node list.")

    util.db_root_arg(parser)
    util.part_arg(parser)
    parser.add_argument('--raw_node_root', required=True)
    parser.add_argument('--error_nodes', default="error_nodes.json")
    parser.add_argument('--ignored_wires')

    args = parser.parse_args()

    processes = min(multiprocessing.cpu_count(), 10)

    print('{} Running {} processes'.format(datetime.datetime.now(), processes))
    pool = multiprocessing.Pool(processes=processes)
    print(
        '{} Reading raw data index'.format(datetime.datetime.now(), processes))
    _, nodes = prjxray.lib.read_root_csv(args.raw_node_root)
    print('{} Reading raw_node_data'.format(datetime.datetime.now()))
    raw_node_data = []
    with progressbar.ProgressBar(max_value=len(nodes)) as bar:
        for idx, node in enumerate(pool.imap_unordered(
                read_json5,
                nodes,
                chunksize=20,
        )):
            bar.update(idx)
            raw_node_data.append(
                (node['node'], tuple(wire['wire'] for wire in node['wires'])))
            bar.update(idx + 1)

    print('{} Creating connections'.format(datetime.datetime.now()))
    generated_nodes = make_connections(args.db_root, args.part)

    print('{} Verifying connections'.format(datetime.datetime.now()))
    error_nodes = []
    prjxray.lib.verify_nodes(raw_node_data, generated_nodes, error_nodes)

    if len(error_nodes) > 0:
        if args.ignored_wires:
            with open(args.ignored_wires, 'r') as f:
                ignored_wires = [l.strip() for l in f.readlines()]

        print(
            '{} Found {} errors, writing errors to {}'.format(
                datetime.datetime.now(),
                len(error_nodes),
                args.error_nodes,
            ))

        with open(args.error_nodes, 'w') as f:
            json.dump(error_nodes, f, indent=2)

        if not args.ignored_wires:
            sys.exit(1)

        if not prjxray.lib.check_errors(error_nodes, ignored_wires):
            print(
                '{} Errors were not ignored via ignored_wires {}'.format(
                    datetime.datetime.now(),
                    args.ignored_wires,
                ))
            sys.exit(1)
        else:
            print(
                '{} All errors were via ignored_wires {}'.format(
                    datetime.datetime.now(),
                    args.ignored_wires,
                ))


if __name__ == '__main__':
    main()
