# Copyright edalize contributors
# Licensed under the 2-Clause BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-2-Clause

import logging
import re
import os
import subprocess

from edalize.edatool import Edatool

logger = logging.getLogger(__name__)

class Veriblelint(Edatool):

    argtypes = ['vlogdefine', 'vlogparam']

    @classmethod
    def get_doc(cls, api_ver):
        if api_ver == 0:
            return {'description' : "Verible lint backend (verible-verilog-lint)",
                    'members': [
                         {'name': 'ruleset',
                          'type': 'String',
                          'desc': 'Ruleset: [default|all|none]'},
                    ],
                    'lists': [
                         {'name' : 'verible_lint_args',
                         'type' : 'String',
                         'desc' : 'Extra command line arguments passed to the Verible tool'},
                         {'name': 'rules',
                          'type': 'String',
                          'desc': 'What rules to use. Prefix a rule name with "-" to disable it.'},
                    ]}


    def build_main(self):
        pass

    def _get_tool_args(self):
        args = [ '--lint_fatal', '--parse_fatal' ]

        if 'rules' in self.tool_options:
            args.append('--rules=' + ','.join(self.tool_options['rules']))
        if 'ruleset' in self.tool_options:
            args.append('--ruleset=' + self.tool_options['ruleset'])
        if 'verible_lint_args' in self.tool_options:
            args += self.tool_options['verible_lint_args']

        return args

    def run_main(self):
        (src_files, incdirs) = self._get_fileset_files(force_slash=True)

        src_files_filtered = []
        config_files_filtered = []
        waiver_files_filtered = []
        for src_file in src_files:
            ft = src_file.file_type

            if ft.startswith("verilogSource") or ft.startswith("systemVerilogSource"):
               src_files_filtered.append(src_file.name)
            elif ft == "veribleLintRules":
               config_files_filtered.append(src_file.name)
            elif ft == "veribleLintWaiver":
               waiver_files_filtered.append(src_file.name)

        if len(src_files_filtered) == 0:
            logger.warning("No SystemVerilog source files to be processed.")
            return

        lint_fail = False
        args = self._get_tool_args()
        if len(config_files_filtered) > 1:
            raise RuntimeError("Verible lint only supports a single rules file (type veribleLintRules)")
        elif len(config_files_filtered) == 1:
            args.append('--rules_config=' + config_files_filtered[0])
        if waiver_files_filtered:
            args.append('--waiver_files=' + ','.join(waiver_files_filtered))

        for src_file in src_files_filtered:
            cmd = ['verible-verilog-lint'] + args + [src_file]
            logger.debug("Running " + ' '.join(cmd))

            try:
                res = subprocess.run(cmd, cwd = self.work_root, check=False)
            except FileNotFoundError:
                _s = "Command '{}' not found. Make sure it is in $PATH"
                raise RuntimeError(_s.format(cmd[0]))

            if res.returncode != 0:
                lint_fail = True
        if lint_fail:
            raise RuntimeError("Lint failed")
