"""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, 10, 11, 24), 'llvmlite.ir.IntType', 'ir.IntType', ({(11, 21, 11, 23): '32'}, {}), '(32)', False, 'from llvmlite import ir\n'), ((15, 13, 15, 26), 'llvmlite.ir.IntType', 'ir.IntType', ({(15, 24, 15, 25): '8'}, {}), '(8)', False, 'from llvmlite import ir\n'), ((17, 16, 17, 90), 'rbc.irutils.get_or_insert_function', 'irutils.get_or_insert_function', (), '', False, 'from rbc import irutils\n'), ((29, 10, 29, 38), 'numba.core.types.void', 'nb_types.void', ({(29, 24, 29, 37): 'nb_types.void'}, {}), '(nb_types.void)', True, 'from numba.core import types as nb_types\n'), ((32, 22, 32, 34), 'rbc.targetinfo.TargetInfo', 'TargetInfo', ({}, {}), '()', False, 'from rbc.targetinfo import TargetInfo\n'), ((48, 41, 48, 76), 'numba.core.types.BaseTuple.from_types', 'nb_types.BaseTuple.from_types', ({(48, 71, 48, 75): 'args'}, {}), '(args)', True, 'from numba.core import types as nb_types\n'), ((51, 26, 51, 38), 'rbc.targetinfo.TargetInfo', 'TargetInfo', ({}, {}), '()', False, 'from rbc.targetinfo import TargetInfo\n'), ((53, 16, 53, 77), 'numba.core.cgutils.printf', 'cgutils.printf', ({(53, 31, 53, 38): 'builder', (53, 40, 53, 65): 'format_type.literal_value', (53, 67, 53, 76): '*args[1:]'}, {}), '(builder, format_type.literal_value, *args[1:])', False, 'from numba.core import cgutils, extending\n')]