#!/usr/bin/env python3

import json
import os
import pathlib
import pprint
import subprocess
import sys

__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(os.path.join(__dir__, "..")))

def main(pdk_path, version):
    pr_path = pathlib.Path(os.path.join(pdk_path, "libraries", "sky130_fd_pr", version))

    devices = []
    with open(os.path.join(__dir__, 'devices.txt')) as f:
        for l in f:
            if '#' in l:
                l = l[:l.index('#')]
            l = l.strip()
            if not l:
                continue

            bits = l.split()
            devices.append(bits[0])

    print()
    print("Devices:")
    print('-'*75)
    pprint.pprint(devices)
    print('-'*75)

    print()
    print("Removing previous runs:")
    print('-'*75)
    for f in pr_path.rglob("*_results.json"):
        f = os.path.abspath(f)
        print(str(f))
        os.unlink(f)
    print('-'*75)

    with subprocess.Popen([
            'parallel', '-v',
            os.path.join(__dir__, 'run_spice_tests_new.py'),
            pdk_path,
            version,
            '{}',
            ], stdin=subprocess.PIPE, stderr=subprocess.STDOUT) as p:
        p.communicate('\n'.join(devices).encode('utf-8'))
        retcode = p.wait()

    passes = []
    fails = []
    ignores = []
    baseline_entries = []
    reasons = {}

    print()
    print("Loading results from:")
    print('-'*75)
    for f in sorted(pr_path.rglob("*_results.json")):
        f = os.path.abspath(f)
        print(str(f))
        with open(f) as f:
            data = json.load(f)
        assert isinstance(data, dict), data
        passes.extend(data.pop('passes'))
        fails.extend(data.pop('fails'))
        ignores.extend(data.pop('ignores'))
        baseline_entries.extend(data.pop('baseline_entries'))
        reasons.update(data.pop('reasons'))
    print('-'*75)
    print()

    output = os.path.join(pr_path, 'simulation_run.log')
    with open(output, 'w') as of:
        print(file=of)
        print('Simulation summary', file=of)
        print('='*75, file=of)
        print(file=of)
        print('Passing devices', file=of)
        print('-'*75, file=of)
        for passing in passes:
            print(passing, file=of)
        print('-'*75, file=of)

        print(file=of)
        print('Ignored (unusable) devices', file=of)
        print('-'*75, file=of)
        for ignored in ignores:
            print(ignored, file=of)
        print('-'*75, file=of)

        print(file=of)
        print('Failing devices', file=of)
        print('-'*75, file=of)
        for failing in fails:
            print(failing, file=of)
            print('   Reason: ' + reasons[failing], file=of)
        print('-'*75, file=of)

        # Output pass / fail / ignore summary

        print(file=of)
        print('Final results', file=of)
        print('#'*75, file=of)
        print('Passes:  ' + str(len(passes)), file=of)
        print('Fails:   ' + str(len(fails)), file=of)
        print('Ignores: ' + str(len(ignores)), file=of)

    print()
    print()
    print()
    with open(output) as f:
        print(f.read())

    return retcode



if __name__ == "__main__":

    args = list(sys.argv)
    args.pop(0)

    pdk_path = args.pop(0)
    if args and args[0] and args[0][0] == 'v':
        version = args.pop(0)
    else:
        version = 'v0.20.1'
    sys.exit(main(pdk_path, version))
