# Copyright Google LLC, 2022
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import logging as log
import sys
import os

from CfgJson import load_hjson

import FormalCfg
import CdcCfg
import RdcCfg
import LintCfg
import dvsim_matcha.SimCfg as SimCfg
import SynCfg


def _load_cfg(path, initial_values):
    '''Worker function for make_cfg.

    initial_values is passed to load_hjson (see documentation there).

    Returns a pair (cls, hjson_data) on success or raises a RuntimeError on
    failure.

    '''
    # Set the `self_dir` template variable to the path of the currently
    # processed Hjson file.
    assert 'self_dir' in initial_values
    initial_values['self_dir'] = os.path.dirname(path)

    # Start by loading up the hjson file and any included files
    hjson_data = load_hjson(path, initial_values)

    # Look up the value of flow in the loaded data. This is a required field,
    # and tells us what sort of FlowCfg to make.
    flow = hjson_data.get('flow')
    if flow is None:
        raise RuntimeError('{!r}: No value for the "flow" key. Are you sure '
                           'this is a dvsim configuration file?'.format(path))

    classes = [
        RdcCfg.RdcCfg, CdcCfg.CdcCfg, LintCfg.LintCfg, SynCfg.SynCfg,
        FormalCfg.FormalCfg, SimCfg.SimCfg
    ]
    found_cls = None
    known_types = []
    for cls in classes:
        assert cls.flow is not None
        known_types.append(cls.flow)
        if cls.flow == flow:
            found_cls = cls
            break
    if found_cls is None:
        raise RuntimeError('{}: Configuration file sets "flow" to {!r}, but '
                           'this is not a known flow (known: {}).'.format(
                               path, flow, ', '.join(known_types)))

    return (found_cls, hjson_data)


def _make_child_cfg(path, args, initial_values):
    try:
        cls, hjson_data = _load_cfg(path, initial_values)
    except RuntimeError as err:
        log.error(str(err))
        sys.exit(1)

    # Since this is a child configuration (from some primary configuration),
    # make sure that we aren't ourselves a primary configuration. We don't need
    # multi-level hierarchies and this avoids circular dependencies.
    if 'use_cfgs' in hjson_data:
        raise RuntimeError(
            '{}: Configuration file has use_cfgs, but is '
            'itself included from another configuration.'.format(path))

    # Call cls as a constructor. Note that we pass None as the mk_config
    # argument: this is not supposed to load anything else.
    return cls(path, hjson_data, args, None)


def make_cfg(path, args, proj_root, titan_root):
    '''Make a flow config by loading the config file at path

    args is the arguments passed to the dvsim.py tool and proj_root is the top
    of the project.

    '''
    initial_values = {
        'proj_root': proj_root,
        'titan_root': titan_root,
        'self_dir': os.path.dirname(path),
    }
    if args.tool is not None:
        initial_values['tool'] = args.tool

    try:
        cls, hjson_data = _load_cfg(path, initial_values)
    except RuntimeError as err:
        log.error(str(err))
        sys.exit(1)

    def factory(child_path):
        child_ivs = initial_values.copy()
        child_ivs['flow'] = hjson_data['flow']
        return _make_child_cfg(child_path, args, child_ivs)

    return cls(path, hjson_data, args, factory)
