#!/usr/bin/env python3
import requests
import argparse
import os
import glob
import json
import yaml
import logging
import sys
import csv
import re
import jinja2

#GPIO_VALID_RANGE = [8, 36]
#GPIO_VALID_RANGE = [0, 38]
GPIO_VALID_RANGE = [0, 38]

def load_yaml(yaml_file):
    with open(yaml_file, "r") as stream:
        return (yaml.safe_load(stream))

def write_user_config(module_name, sources, io_ranges):
    env = jinja2.Environment(
        loader = jinja2.FileSystemLoader('verilog/rtl')
    )
    top_module_template = env.get_template('tiny_user_project.v.jinja2')
    with open('verilog/rtl/tiny_user_project.v', 'w') as fh:
        fh.write(top_module_template.render(
            module_name=module_name,
            io_in_range=io_ranges[0],
            io_out_range=io_ranges[1]
        ))
    user_defines_template = env.get_template('user_defines.v.jinja2')
    with open('verilog/rtl/user_defines.v', 'w') as fh:
        fh.write(user_defines_template.render(
            io_in_range=io_ranges[0],
            io_out_range=io_ranges[1]
        ))
    with open('openlane/tiny_user_project/config.json', 'r') as fh:
        config_json = json.load(fh)
    sources.append('verilog/rtl/defines.v')
    sources.append('verilog/rtl/tiny_user_project.v')
    config_json['VERILOG_FILES'] = [f'dir::../../{s}' for s in sources]
    with open('openlane/tiny_user_project/config.json', 'w') as fh:
        json.dump(config_json, fh, indent=4)

def get_project_source(yaml):
    # wokwi_id must be an int or 0
    try:
        wokwi_id = int(yaml['project']['wokwi_id'])
    except ValueError:
        logging.error("wokwi id must be an integer")
        exit(1)

    # it's a wokwi project
    if wokwi_id != 0:
        url = "https://wokwi.com/api/projects/{}/verilog".format(wokwi_id)
        logging.info("trying to download {}".format(url))
        r = requests.get(url)
        if r.status_code != 200:
            logging.warning("couldn't download {}".format(url))
            exit(1)

        filename = "user_module.v"
        with open(os.path.join('verilog/rtl', filename), 'wb') as fh:
            fh.write(r.content)

        # also fetch the wokwi diagram
        url = "https://wokwi.com/api/projects/{}/diagram.json".format(wokwi_id)
        logging.info("trying to download {}".format(url))
        r = requests.get(url)
        if r.status_code != 200:
            logging.warning("couldn't download {}".format(url))
            exit(1)

        with open(os.path.join('verilog/rtl', "wokwi_diagram.json"), 'wb') as fh:
            fh.write(r.content)

        return [f'verilog/rtl/{filename}', 'verilog/rtl/cells.v']

    # else it's HDL, so check source files
    else:
        if 'source_files' not in yaml['project']:
            logging.error("source files must be provided if wokwi_id is set to 0")
            exit(1)

        source_files = yaml['project']['source_files']
        if source_files is None:
            logging.error("must be more than 1 source file")
            exit(1)

        if len(source_files) == 0:
            logging.error("must be more than 1 source file")
            exit(1)

        if 'top_module' not in yaml['project']:
            logging.error("must provide a top module name")
            exit(1)

        return source_files


# documentation
def check_docs(yaml):
    for key in ['author', 'title', 'description', 'how_it_works', 'how_to_test', 'language']:
        if key not in yaml['documentation']:
            logging.error("missing key {} in documentation".format(key))
            exit(1)
        if yaml['documentation'][key] == "":
            logging.error("missing value for {} in documentation".format(key))
            exit(1)

    # if provided, check discord handle is valid
    if len(yaml['documentation']['discord']):
        parts = yaml['documentation']['discord'].split('#')
        if len(parts) != 2 or len(parts[0]) == 0 or not re.match('^[0-9]{4}$', parts[1]):
            logging.error(f'Invalid format for discord username')
            exit(1)


def get_top_module(yaml):
    wokwi_id = int(yaml['project']['wokwi_id'])
    if wokwi_id != 0:
        return "user_module_{}".format(wokwi_id)
    else:
        return yaml['project']['top_module']

def get_io_ranges(yaml):
    input_range = (GPIO_VALID_RANGE[0], GPIO_VALID_RANGE[0]+len(yaml['documentation']['inputs']))
    output_range = (input_range[1], input_range[1]+len(yaml['documentation']['outputs']))
    gpio_end = output_range[1]
    if gpio_end > GPIO_VALID_RANGE[1]:
        raise Exception('ETOOMANY IOs')
    return (input_range, output_range)

def get_stats():
    with open('runs/wokwi/reports/metrics.csv') as f:
        report = list(csv.DictReader(f))[0]

    print('# Routing stats')
    print()
    print('| Utilisation | Wire length (um) |')
    print('|-------------|------------------|')
    print('| {} | {} |'.format(report['OpenDP_Util'], report['wire_length']))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="TT setup")

    parser.add_argument('--check-docs', help="check the documentation part of the yaml", action="store_const", const=True)
    parser.add_argument('--get-stats', help="print some stats from the run", action="store_const", const=True)
    parser.add_argument('--create-user-config', help="create the user_config.tcl file with top module and source files", action="store_const", const=True)
    parser.add_argument('--debug', help="debug logging", action="store_const", dest="loglevel", const=logging.DEBUG, default=logging.INFO)
    parser.add_argument('--yaml', help="yaml file to load", default='info.yaml')

    args = parser.parse_args()
    # setup log
    log_format = logging.Formatter('%(asctime)s - %(module)-10s - %(levelname)-8s - %(message)s')
    # configure the client logging
    log = logging.getLogger('')
    # has to be set to debug as is the root logger
    log.setLevel(args.loglevel)

    # create console handler and set level to info
    ch = logging.StreamHandler(sys.stdout)
    # create formatter for console
    ch.setFormatter(log_format)
    log.addHandler(ch)

    if args.get_stats:
        get_stats()

    elif args.check_docs:
        logging.info("checking docs")
        config = load_yaml(args.yaml)
        check_docs(config)

    elif args.create_user_config:
        logging.info("creating include file")
        config = load_yaml(args.yaml)
        source_files = get_project_source(config)
        top_module = get_top_module(config)
        assert top_module != 'top'
        io_ranges = get_io_ranges(config)
        write_user_config(top_module, source_files, io_ranges)
