"""
Set of utilities to build a simple test suite.
"""
from amaranth import *
from amaranth.sim import *

from typing import Generator
import unittest
import os

from contextlib import nullcontext

class BaseTestClass(unittest.TestCase):
    """
    Base test class that provides a run_test helper function to do all the nice things.
    """

    def _run_test(self, test: Generator, name: str):
        try:
            sim = Simulator(self.harness)
        except NameError:
            raise NotImplementedError(f"Must define a self.harness module for TestCase {self.__class__.__name__}!")

        sim.add_clock(100e-9)
        sim.add_sync_process(test)
        sim.reset()

        # Pretty hacky way to pass this info in but does it look like I care?
        if os.environ.get("TEST_SAVE_VCD"):
           ctx = sim.write_vcd(f"vcd_out/{name}.vcd")
        else:
            ctx = nullcontext()

        with ctx:
            sim.run()

        del sim


def provide_testcase_name(fn):
    """Decorator that provides a function with access to its own class and name."""
    def wrapper(self):
        fn(self, f"{self.__class__.__name__}.{fn.__name__}")

    return wrapper
