from llvmlite import binding as ll
# from llvmlite.llvmpy import core as lc
import llvmlite.ir as llvmir
from numba.core import utils
from numba.core.codegen import Codegen, CodeLibrary, CPUCodeLibrary
from .hlc import DATALAYOUT, TRIPLE, hlc

class HSACodeLibrary(CPUCodeLibrary):
    def _optimize_functions(self, ll_module):
        pass

    def _optimize_final_module(self):
        pass

    def _finalize_specific(self):
        pass

    def get_asm_str(self):
        """
        Get the human-readable assembly.
        """
        m = hlc.Module()
        m.load_llvm(str(self._final_module))
        out = m.finalize()
        return str(out.hsail)


# class JITHSACodegen(Codegen):
#     _library_class = HSACodeLibrary

#     def _init(self, llvm_module):
#         assert list(llvm_module.global_variables) == [], "Module isn't empty"
#         self._data_layout = DATALAYOUT[utils.MACHINE_BITS]
#         self._target_data = ll.create_target_data(self._data_layout)

#     def _create_empty_module(self, name):
#         ir_module = llvmir.Module(name)
#         ir_module.triple = TRIPLE
#         return ir_module

#     def _module_pass_manager(self):
#         raise NotImplementedError

#     def _function_pass_manager(self, llvm_module):
#         raise NotImplementedError

#     def _add_module(self, module):
#         pass

class JITHSACodegen(Codegen):
    _library_class = HSACodeLibrary

    def __init__(self, module_name):
        # initialize_llvm()
        ll.initialize()
        ll.initialize_native_target()
        ll.initialize_native_asmprinter()

        self._data_layout = None
        self._llvm_module = ll.parse_assembly(
            str(self._create_empty_module(module_name)))
        self._llvm_module.name = "global_codegen_module"
        # self._rtlinker = RuntimeLinker()
    
        self._init(self._llvm_module)

    def _init(self, llvm_module):
        assert list(llvm_module.global_variables) == [], "Module isn't empty"
        self._data_layout = DATALAYOUT[utils.MACHINE_BITS]
        self._target_data = ll.create_target_data(self._data_layout)

    def _create_empty_module(self, name):
        ir_module = llvmir.Module(name)
        ir_module.triple = TRIPLE
        if self._data_layout:
            ir_module.data_layout = self._data_layout
        return ir_module

    def _module_pass_manager(self):
        raise NotImplementedError

    def _function_pass_manager(self, llvm_module):
        raise NotImplementedError

    def _add_module(self, module):
        pass
