"""https://en.cppreference.com/w/c/io
"""

from rbc import irutils
from llvmlite import ir
from rbc.targetinfo import TargetInfo
from numba.core import cgutils, extending
from numba.core import types as nb_types
from rbc.errors import NumbaTypeError  # some errors are available for Numba >= 0.55

int32_t = ir.IntType(32)


def cg_fflush(builder):
    int8_t = ir.IntType(8)
    fflush_fnty = ir.FunctionType(int32_t, [int8_t.as_pointer()])
    fflush_fn = irutils.get_or_insert_function(builder.module, fflush_fnty, name="fflush")

    builder.call(fflush_fn, [int8_t.as_pointer()(None)])


@extending.intrinsic
def fflush(typingctx):
    """``fflush`` that can be called from Numba jit-decorated functions.

    .. note::
        ``fflush`` is available only for CPU target.
    """
    sig = nb_types.void(nb_types.void)

    def codegen(context, builder, signature, args):
        target_info = TargetInfo()
        if target_info.is_cpu:
            cg_fflush(builder)

    return sig, codegen


@extending.intrinsic
def printf(typingctx, format_type, *args):
    """``printf`` that can be called from Numba jit-decorated functions.

    .. note::
        ``printf`` is available only for CPU target.
    """

    if isinstance(format_type, nb_types.StringLiteral):
        sig = nb_types.void(format_type, nb_types.BaseTuple.from_types(args))

        def codegen(context, builder, signature, args):
            target_info = TargetInfo()
            if target_info.is_cpu:
                cgutils.printf(builder, format_type.literal_value, *args[1:])
                cg_fflush(builder)

        return sig, codegen

    else:
        raise NumbaTypeError(f"expected StringLiteral but got {type(format_type).__name__}")

[(11, 'llvmlite.ir.IntType', 'ir.IntType', False, 'from llvmlite import ir\n'), (15, 'llvmlite.ir.IntType', 'ir.IntType', False, 'from llvmlite import ir\n'), (17, 'rbc.irutils.get_or_insert_function', 'irutils.get_or_insert_function', False, 'from rbc import irutils\n'), (29, 'numba.core.types.void', 'nb_types.void', True, 'from numba.core import types as nb_types\n'), (32, 'rbc.targetinfo.TargetInfo', 'TargetInfo', False, 'from rbc.targetinfo import TargetInfo\n'), (48, 'numba.core.types.BaseTuple.from_types', 'nb_types.BaseTuple.from_types', True, 'from numba.core import types as nb_types\n'), (51, 'rbc.targetinfo.TargetInfo', 'TargetInfo', False, 'from rbc.targetinfo import TargetInfo\n'), (53, 'numba.core.cgutils.printf', 'cgutils.printf', False, 'from numba.core import cgutils, extending\n')]