def tenon(rail, stile, offsets, tenon, mortise_bit_diameter, bit_diameter,
          safe_Z, cut_per_pass):
    """
    Assumed bit location (center) is at refs origin, at safe_Z, and machine is assumed in ABS mode.
    It is usual that mortise_bit_diameter == bit_diameter.
    Requires:
        rail = (rail_face_width, rail_thickness)
        stile = (stile_face_width, stile_thickness)
        offsets = (offset_from_face, offset_from_end)
        tenon = (length, width, depth)
    """
    # Unpacking the tuples
    rail_face_width, rail_thickness = rail
    stile_face_width, stile_thickness = stile
    offset_from_face, offset_from_end = offsets
    length, width, depth = tenon

    bit_radius = bit_diameter / 2.0
    corner_radius = mortise_bit_diameter / 2.0

    file_text = ''

    # if debug:
    #     file_text += "; target_depth: " + str(target_depth) + "\n"
    #     file_text += "; stock_thickness: " + str(stock_thickness) + "\n"
    #     file_text += "; cut_per_pass: "******"\n"
    #     file_text += "; bit_diameter: " + str(bit_diameter) + "\n"

    if (offset_from_face <= bit_diameter) and (offset_from_end <= bit_diameter) and \
        (rail_face_width - offset_from_end - length <= bit_diameter) and \
        (rail_thickness - offset_from_face - width <= bit_diameter):
        file_text += G.set_ABS_mode()
        file_text += G.G0_Z(safe_Z)
        file_text += G.set_INCR_mode()
        file_text += G.G0_X(offset_from_end + corner_radius)
        file_text += G.set_ABS_mode()
        file_text += G.G0_Z(stile_face_width)
        # Making target_depth a reference from machine's Z = 0.
        target_depth = stile_face_width - depth
        while stile_face_width > target_depth:
            stile_face_width -= cut_per_pass
            if stile_face_width < target_depth:
                stile_face_width = target_depth
            # Z-axis move by ABSOLUTE coords
            file_text += G.set_ABS_mode()
            file_text += G.G1_Z(stile_face_width)

            file_text += G.set_INCR_mode()
            file_text += roundedRectangle(length, width, mortise_bit_diameter,
                                          bit_diameter, 'inside')
    else:
        file_text = 'Not implemented yet'

    file_text += G.set_ABS_mode()
    file_text += G.G0_Z(safe_Z)
    return file_text