# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Modified from bazel_rules_hdl to use SystemC
"""Functions for verilator."""

load("@rules_hdl//verilog:providers.bzl", "VerilogInfo")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")

def cc_compile_and_link_static_library(ctx, srcs, hdrs, deps, runfiles, includes = [], defines = []):
    """Compile and link C++ source into a static library

    Args:
        ctx: Context for rule
        srcs: The cpp sources generated by verilator.
        hdrs: The headers generated by verilator.
        deps: Library dependencies to build with.
        runfiles: Data dependencies that are read at runtime.
        includes: The includes for the verilator module to build.
        defines: Cpp defines to build with.

    Returns:
        CCInfo with the compiled library.
    """
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )

    compilation_contexts = [dep[CcInfo].compilation_context for dep in deps]
    compilation_context, compilation_outputs = cc_common.compile(
        name = ctx.label.name,
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        srcs = srcs,
        includes = includes,
        defines = defines,
        public_hdrs = hdrs,
        compilation_contexts = compilation_contexts,
    )

    linking_contexts = [dep[CcInfo].linking_context for dep in deps]
    linking_context, linking_output = cc_common.create_linking_context_from_compilation_outputs(
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        compilation_outputs = compilation_outputs,
        linking_contexts = linking_contexts,
        name = ctx.label.name,
        disallow_dynamic_library = True,
    )

    output_files = []
    if linking_output.library_to_link.static_library != None:
        output_files.append(linking_output.library_to_link.static_library)
    if linking_output.library_to_link.dynamic_library != None:
        output_files.append(linking_output.library_to_link.dynamic_library)

    return [
        DefaultInfo(files = depset(output_files), runfiles = ctx.runfiles(files = runfiles)),
        CcInfo(
            compilation_context = compilation_context,
            linking_context = linking_context,
        ),
    ]

_CPP_SRC = ["cc", "cpp", "cxx", "c++"]
_HPP_SRC = ["h", "hh", "hpp"]
_RUNFILES = ["dat", "mem"]

def _only_cpp(f):
    """Filter for just C++ source/headers"""
    if f.extension in _CPP_SRC + _HPP_SRC:
        return f.path
    return None

def _only_hpp(f):
    """Filter for just C++ headers"""
    if f.extension in _HPP_SRC:
        return f.path
    return None

_COPY_TREE_SH = """
OUT=$1; shift && mkdir -p "$OUT" && cp $* "$OUT"
"""

def _copy_tree(ctx, idir, odir, map_each = None, progress_message = None):
    """Copy files from a TreeArtifact to a new directory"""
    args = ctx.actions.args()
    args.add(odir.path)
    args.add_all([idir], map_each = map_each)
    ctx.actions.run_shell(
        arguments = [args],
        command = _COPY_TREE_SH,
        inputs = [idir],
        outputs = [odir],
        progress_message = progress_message,
    )

    return odir

def _verilator_cc_library(ctx):
    transitive_srcs = depset([], transitive = [ctx.attr.module[VerilogInfo].dag])
    all_srcs = [verilog_info_struct.srcs for verilog_info_struct in transitive_srcs.to_list()]
    all_files = [src for sub_tuple in all_srcs for src in sub_tuple]

    # Filter out .dat files.
    runfiles = []
    verilog_files = []
    for file in all_files:
        if file.extension in _RUNFILES:
            runfiles.append(file)
        else:
            verilog_files.append(file)

    verilator_output = ctx.actions.declare_directory(ctx.label.name + "-gen")
    verilator_output_cpp = ctx.actions.declare_directory(ctx.label.name + ".cpp")
    verilator_output_hpp = ctx.actions.declare_directory(ctx.label.name + ".h")

    prefix = "V" + ctx.attr.module_top

    args = ctx.actions.args()
    args.add("--sc")
    args.add("--pins-bv", "2")
    args.add("--Mdir", verilator_output.path)
    args.add("--top-module", ctx.attr.module_top)
    args.add("--prefix", prefix)
    verilog_dirs = dict()
    for file in verilog_files:
        verilog_dirs[file.dirname] = None
    for vdir in verilog_dirs:
        args.add("-I" + vdir)
    if ctx.attr.trace:
        args.add("--trace")
    for verilog_file in verilog_files:
        args.add(verilog_file.path)
    args.add("-Wno-UNOPTFLAT")
    args.add_all(ctx.attr.vopts, expand_directories = False)

    ctx.actions.run(
        arguments = [args],
        executable = ctx.executable._verilator,
        inputs = verilog_files,
        outputs = [verilator_output],
        progress_message = "[Verilator] Compiling {}".format(ctx.label),
    )

    _copy_tree(
        ctx,
        verilator_output,
        verilator_output_cpp,
        map_each = _only_cpp,
        progress_message = "[Verilator] Extracting C++ source files",
    )
    _copy_tree(
        ctx,
        verilator_output,
        verilator_output_hpp,
        map_each = _only_hpp,
        progress_message = "[Verilator] Extracting C++ header files",
    )

    # Do actual compile
    defines = ["VM_TRACE"] if ctx.attr.trace else []
    deps = [ctx.attr._verilator_lib, ctx.attr._zlib, ctx.attr._verilator_svdpi]

    return cc_compile_and_link_static_library(
        ctx,
        srcs = [verilator_output_cpp],
        hdrs = [verilator_output_hpp],
        defines = defines,
        runfiles = runfiles,
        includes = [verilator_output_hpp.path],
        deps = deps,
    )

verilator_cc_library = rule(
    _verilator_cc_library,
    attrs = {
        "module": attr.label(
            doc = "The top level module target to verilate.",
            providers = [VerilogInfo],
            mandatory = True,
        ),
        "module_top": attr.string(
            doc = "The name of the verilog module to verilate.",
            mandatory = True,
        ),
        "trace": attr.bool(
            doc = "Enable tracing for Verilator",
            default = True,
        ),
        "vopts": attr.string_list(
            doc = "Additional command line options to pass to Verilator",
            default = ["-Wall"],
        ),
        "_cc_toolchain": attr.label(
            doc = "CC compiler.",
            default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
        ),
        "_verilator": attr.label(
            doc = "Verilator binary.",
            executable = True,
            cfg = "exec",
            default = Label("@verilator//:verilator_executable"),
        ),
        "_verilator_lib": attr.label(
            doc = "Verilator library",
            default = Label("@verilator//:libverilator"),
        ),
        "_verilator_svdpi": attr.label(
            doc = "Verilator svdpi lib",
            default = Label("@verilator//:svdpi"),
        ),
        "_zlib": attr.label(
            doc = "zlib dependency",
            default = Label("@net_zlib//:zlib"),
        ),
    },
    provides = [
        CcInfo,
        DefaultInfo,
    ],
    toolchains = [
        "@bazel_tools//tools/cpp:toolchain_type",
    ],
    fragments = ["cpp"],
)
